C# 系统应用之透明罩MyOpaqueLayer实现360界面阴影效果

在完成“个人电脑使用记录清除软件”中,我设计的winform界面需要应用到类似于"360安全卫士"的透明罩效果,文章主要引述了如何使用自定义组件MyOpaqueLayer,并自定义类OpaqueCommand中定义显示透明罩函数ShowOpaqueLayer和隐藏透明罩函数HideOpaqueLayer实现,同时如何对控件添加透明罩及遇到的问题.

一.自定义透明罩MyOpaqueLayer组件

(声明:此段代码引用自海华博客http://www.cnblogs.com/JuneZhang/archive/2012/07/06/2579215.html)
在添加透明罩控件\组件时,我的想法是"右键项目->添加->添加控件",但添加没有成功,在网上也没有讲到该添加的基础方法,由于以前也没遇到过自定义控件的问题,所以只好采取的方法是拖拽修改过MyOpaqueLayer.cs文件至项目中,具体代码如下(含详细注释):

using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

namespace MyOpaqueLayer
{
    /*
     * [ToolboxBitmap(typeof(MyOpaqueLayer))]
     * 用于指定当把你做好的自定义控件添加到工具栏时,工具栏显示的图标。
     * 正确写法应该是
     * [ToolboxBitmap(typeof(XXXXControl),"xxx.bmp")]
     * 其中XXXXControl是你的自定义控件,"xxx.bmp"是你要用的图标名称。
    */
    [ToolboxBitmap(typeof(MyOpaqueLayer))]

    /// <summary>
    /// 自定义控件:透明罩控件(继承Control)
    /// </summary>
    public class MyOpaqueLayer : System.Windows.Forms.Control
    {
        private bool _transparentBG = true;       //是否使用透明
        private int _alpha = 125;                 //设置透明度

        private System.ComponentModel.Container components = new System.ComponentModel.Container();
        public MyOpaqueLayer()
            : this(125, true)
        {
        }

        public MyOpaqueLayer(int Alpha, bool IsShowLoadingImage)
        {
            SetStyle(System.Windows.Forms.ControlStyles.Opaque, true);  //设置控件样式
            base.CreateControl();                                       //创建控件
            this._alpha = Alpha;
            //放置加载进度的图片代码此处被省略
        }

        //释放组件占用内存
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (!((components == null)))
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        /// <summary>
        /// 自定义绘制窗体
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            float vlblControlWidth;
            float vlblControlHeight;

            Pen labelBorderPen;                     //定义Pen
            SolidBrush labelBackColorBrush;         //定义单色画笔

            if (_transparentBG)                     //使用透明
            {
                Color drawColor = Color.FromArgb(this._alpha, this.BackColor);
                labelBorderPen = new Pen(drawColor, 0);
                labelBackColorBrush = new SolidBrush(drawColor);
            }
            else
            {
                labelBorderPen = new Pen(this.BackColor, 0);
                labelBackColorBrush = new SolidBrush(this.BackColor);
            }
            base.OnPaint(e);
            vlblControlWidth = this.Size.Width;
            vlblControlHeight = this.Size.Height;
            e.Graphics.DrawRectangle(labelBorderPen, 0, 0, vlblControlWidth, vlblControlHeight);
            e.Graphics.FillRectangle(labelBackColorBrush, 0, 0, vlblControlWidth, vlblControlHeight);
        }

        //获取创建控件句柄时所需要的创建参数
        protected override CreateParams CreateParams //v1.10
        {
            get
            {
                CreateParams cp = base.CreateParams;  //扩展派生类CreateParams属性
                cp.ExStyle |= 0x00000020;             //开启WS_EX_TRANSPARENT,使控件支持透明
                return cp;
            }
        }

        /*
         * [Category("myOpaqueLayer"), Description("是否使用透明,默认为True")]
         * 一般用于说明你自定义控件的属性(Property)
         * Category用于说明该属性属于哪个分类,Description自然就是该属性的含义解释。
         */
        [Category("MyOpaqueLayer"), Description("是否使用透明,默认为True")]
        public bool TransparentBG
        {
            get
            {
                return _transparentBG;
            }
            set
            {
                _transparentBG = value;
                this.Invalidate();
            }
        }
        //设置透明度
        [Category("MyOpaqueLayer"), Description("设置透明度")]
        public int Alpha
        {
            get
            {
                return _alpha;
            }
            set
            {
                _alpha = value;
                this.Invalidate();
            }
        }

        //初始化窗体
        private void InitializeComponent()
        {
            this.SuspendLayout();      //临时挂起控件的布局逻辑,它与ResumeLayout()配合使用
            this.ResumeLayout(false);  //恢复正常逻辑
        }
    }
}

二.自定义透明罩类OpaqueCommand

在第一部分我们已经自定义透明罩组件,此时需要自定义类OpaqueCommand并调用其方法ShowOpaqueLayer(显示遮罩层)和HideOpaqueLayer(隐藏遮罩层).可以在“解决方法”中右键项目名->添加->类,具体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EMSecure
{
    class OpaqueCommand
    {
        //透明罩
        private MyOpaqueLayer.MyOpaqueLayer m_OpaqueLayer = null;

        /// <summary>
        /// 显示透明层
        /// </summary>
        /// <param name="control">控件</param>
        /// <param name="alpha">透明度</param>
        /// <param name="isShowLoadingImage">是否显示图标</param>
        public void ShowOpaqueLayer(Control control, int alpha, bool isShowLoadingImage)
        {
            try
            {
                if (this.m_OpaqueLayer == null)
                {
                    this.m_OpaqueLayer = new MyOpaqueLayer.MyOpaqueLayer(alpha, isShowLoadingImage);
                    control.Controls.Add(this.m_OpaqueLayer);
                    this.m_OpaqueLayer.Dock = DockStyle.Fill;
                    this.m_OpaqueLayer.BringToFront();
                }
                this.m_OpaqueLayer.Enabled = true;
                this.m_OpaqueLayer.Visible = true;
            }
            catch (Exception msg)              //异常处理
            {
                MessageBox.Show(msg.Message);
            }
        }

        /// <summary>
        /// 隐藏透明层
        /// </summary>
        public void HideOpaqueLayer()
        {
            try
            {
                if (this.m_OpaqueLayer != null)
                {
                    this.m_OpaqueLayer.Visible = false;
                    this.m_OpaqueLayer.Enabled = false;
                }
            }
            catch (Exception msg)             //异常处理
            {
                MessageBox.Show(msg.Message);
            }
        }
    }
}

三.使用透明罩

在定义透明罩控件和类后,如何实现该界面的效果,我推荐的方法是:
1.设置toolBar控件,在items(集合)中添加相应的图标\文字构成不同的ToolItem,每次透明罩遮掩不同的Item即可,如果是wfp使用TabControl\TabItem.但由于toolBar被toolStrip替代,不太会使用该控件,但仍然推荐该方法(有的没有定义透明罩控件,而是通过3张透明程度不同的图,设置可见属性实现该效果).运行结果:


2.在代码设计器Form中添加MyOpaqueLayer控件,此时就能看见6个透明罩的MyOpaqueLayer控件,该方法不需要设置自定义类OpaqueCommand调用其方法,而是设置如下代码:

//鼠标离开
private void myOpaqueLayer1_MouseLeave(object sender, EventArgs e)
{
    this.myOpaqueLayer1.Visible = false;
    this.label4.ForeColor = Color.White;
}
//鼠标进入
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
    this.myOpaqueLayer1.Visible = true;
    this.label4.ForeColor = Color.Yellow;
}

设计器中form如下图所示:

但由于不知道如何添加该控件拖动至设计器中,所以我采取的方法是
3.自定义6个panel,通过鼠标事件进入panelmol1_MouseEnter(object sender, EventArgs e)\鼠标离开事件panelmol1_MouseLeave(object sender, EventArgs e)\鼠标点击事件panelmol1_MouseClick(object sender, EventArgs e)实现,最后我的运行结果如下图所示:


下面只给出使用透明罩控件和类的基本调用代码并省略Click部分(因为做的不是很好),请读者体会与自己设计:

//自定义类OpaqueCommand
OpaqueCommand cmd = new OpaqueCommand();
//定义点击panel时透明罩情况
bool isClick = false;

//鼠标进入"清除IE"
private void panel_mol1_MouseEnter(object sender, EventArgs e)
{
    //透明罩设置 没点击才取消透明罩
    cmd.ShowOpaqueLayer(panel_mol1, 125, true);
}
private void panel_mol1_MouseEnter(object sender, EventArgs e)
{
    cmd.HideOpaqueLayer();
}

四.总结
个人感觉该设计还有很多地方需要自己改进,同时想实现ToolBar方法和了解如何添加自定义组件而不是拖拽,期望自己能解决这些问题.希望该文章对大家有所帮助,同时感谢下面3篇文章及博主,是讲述透明罩和如何自定义控件的文章,个人感觉非常不错.如果文章中有不足或错误的地方,请海涵!
(By:Eastmount 2014-3-10 中午2点 原创:http://blog.csdn.net/eastmount)
参考资料及在线笔记:
1.C#实现Winform自定义半透明遮罩层-海华(主要参考透明罩的设定)
http://www.cnblogs.com/JuneZhang/archive/2012/07/06/2579215.html
2.C#中自定义控件-杨友山(自定义控件简述)
http://blog.csdn.net/yysyangyangyangshan/article/details/7078471
3.C#自定义控件开发-百度文库(详细介绍自定义控件\复合控件\扩展控件)
http://wenku.baidu.com/view/89a47f6e58fafab069dc02bf.html

时间: 2024-08-02 23:47:34

C# 系统应用之透明罩MyOpaqueLayer实现360界面阴影效果的相关文章

xp系统关机时会卡在正在关机界面

现在使用xp系统的人很多,而现在系统中各种软件对于系统内存的要求越来越高,这导致很多人在关闭系统的时候,会出现xp系统关机时会卡在正在关机界面.而且如果你用电脑都是开一样的软件,然后关机的时候都是一样的习惯也很有可能导致你关机的时候,次次都会卡在这个界面,特别是对于一些玩游戏的人来说. 1 xp系统关机时会卡在正在关机界面的原因: 1:磁盘空间太少,或者垃圾文件太多,没有清理 2:关机时,电脑还有很多软件或者游戏在运行,导致了电脑在关机界面的时候卡住了. 3:一些软件的安装和卸载不彻底,导致了关

win7系统连接宽带时没有出现连接界面是怎么回事?

  win7系统连接宽带时没有出现连接界面是怎么回事? 1.点击右下角"网络"图标打开"网络和共享中心"; 2.然后点击更改适配器设置; 3.打开后,右键点击"宽带连接"选择属性; 4.在选项中,勾选"连接时显示进度"和"提示名称.密码和证书"确定即可.

win7系统双击文件夹弹出搜索界面的解决方法

  其实win7系统一直很稳定,但时间久了必然会出现一定的问题,下面小编就为大家介绍一个不常出现,但是一旦出现又很麻烦的问题.win7旗舰版系统双击文件夹弹出搜索界面,这两个看似不可能同时出现的页面却出现在了一起.只有当右键打开才能正常打开文件夹阅读文件,这个情况的发生不是我们人为设置的,只有可能是我们无意中将右键菜单中多了一个搜索,而默认使用搜索打开导致的.我们只需要将默认使用打开文件就可以了.下面小编就来教大家这个方法. 解决双击文件夹弹出搜索界面的方法 1.打开注册表编辑器(在运行中输入

以system用户运行的系统及服务,无法显示java界面

问题描述 以system用户运行的系统及服务,无法显示java界面 标题:csdn无法写标题了,我的问题在描述里,谢谢在线等 我用一个java程序作为一个系统服务启动(**用户为System**),现在想让他定时监控一个 程序是否启动,如果没有启动调用runtime.getRuntime.exec 启动一个exe程序(这个程序使用swt写的) 现在的问题是启动这个exe时,能够执行runtime,在任务管理器中也存在相应进程 但是**无法显示界面**, 问题总结描述:以system用户运行的系统

C# 高手,求一款浏览器类似360界面

问题描述 C#高手,求一款浏览器类似360界面需要源代码,赏金500元有兴趣的加QQ:271398601详细谈! 解决方案 解决方案二:路过解决方案三:...500?楼主在买白菜?现在白菜好像都涨价了!解决方案四:话说有一种方法1分钟完成浏览器只要3个控件解决方案五:如果大家都认为钱少了,我可以增加!解决方案六:这个可以有,下面回答!解决方案七:有没有人可以做啊解决方案八:有没有人可以做啊解决方案九:myblog解决方案十:擦crackdung大大这个不错哦不知道有没破解版发布下解决方案十一:想

怎么把系统桌面的快捷键添加到360安全桌面

  方法一 在安全桌面全屏模式下,直接点击右键,菜单里点选添加本机程序和网址. 选择添加文件 浏览路径 桌面上选中要加的软件快捷方式 这样就好了 方法二 退出全屏模式,直接拖放快捷方式过去

win7系统以前从来没蓝屏过360软件管家升级迅雷7后蓝屏

  [解决方法] [1]可尝试到迅雷7中的系统设置 =>外观设置 =>特效等级 =>选择"关闭". [2]联系客服,获取具体蓝屏信息进行定位,客服电话:4001111000

Windows 8系统下打造属于自己的个性界面的方法

目前Windows的个性化一直以来都是用户们比较关注的一个方面,Windows 8在这方面做的就相对好一些.Windows 8中拥有全新的Modern UI设计,因此Windows 8的个性化设置也将分为传统桌面和Modern界面两个方面: 1.首先我们先看看传统界面下的个性化设置. 与Windows 7的操作方式相同,大家可以在桌面右击鼠标,在菜单中选择"个性化"来进入个性化设置界面.此外,大家也可以将鼠标移至桌面的右上角或右下角呼出Charm栏,然后在"设置"选

window8系统如何让天气显示在metro界面中

  1.安装好window8系统点击左下角的开始菜单出现如下界面 2.打开之后点击上面一个天气的方块就可以了出现如下界面就表示可以正常使用 3,再出现的对话框中选择所在的省市就可以显示了