C#制作高仿360安全卫士窗体<二>_a_18291513321的博客-程序员宅基地

技术标签: c#  ui  

继上次C#制作高仿360安全卫士窗体<一>发布之后响应还不错,我的博客放肆雷特也来了不少的新朋友,在这里先谢谢大家的支持!我自己也反复看了一下觉得对不起大家,写的非常乱而且很少文字介绍。在这里先说明一下,我是一个纯粹想搞技术的,文笔较差。我也想锻炼自己所以才会慢慢的将自己的所学分享出来。一来可以锻炼自己的文笔,二来可以分享知识留给像我一样喜欢这些东西的朋友。所以以后如果缺少介绍和说明,请大家多多补充指正,相互提高。下面进入主题。 上一篇主要讲的如何绘制一个按钮,那么今天讲解如何绘制窗体。之前也说过,先制作按钮的作用是可以将按钮用到窗体上面那些系统按钮如最大化、最小化、关闭、还原等。首先我们对按钮的不同状态的图片进行提取,在上一篇提出来皮肤文件之后,将按钮的文件sys_button_max.png,sys_button_min.png,sys_button_close.png,sys_button_max.png,sys_button_restore.png这几个图片文件进行提取。在这里说明,可以直接使用,也可以自己进行加工。以下是我加工过的(如果需要可以直接右键另存为)

 

一、嵌入资源 图片素材准备好之后在解决方案中Images目录里面建立一个FormImages文件夹,将图片素材拷贝进去,并设置图片属性中生成操作选择为“嵌入的资源”。 二、创建窗体 资源嵌入之后再在ControlEx目录中建立一个FormEx文件夹,在该文件夹下创建一个名为BaseForm的窗体。该窗体需要修改的选项很少,大部分可以使用代码来解决。窗体创建完毕后,将创建好的ButtonEx拖进窗体,这里需要拖放5个。为了使内容更好看,还拖一个Panel进来。摆放的位置可以随意,后期通过代码控制,但是为了便于开发我摆放为如下:

 

三、编码

控件摆放完了之后就可以开始编码了,窗体编码主要难度在于消息的处理还有一个比较麻烦一点的是窗体中不同状态下按钮的位置处理,我直接上代码不懂的留言询问我再详细解答:

1、变量申明

 1 #region 声明
 2 private int Rgn;
 3 private Graphics g;
 4 private bool _IsResize = true;//是否允许改变窗口大小
 5 private FormSystemBtn _FormSystemBtnSet = FormSystemBtn.SystemAll;
 6 private Bitmap btn_closeImg = ImageObject.GetResBitmap("FANGSI.UI.Images.FormImages.btn_close.png");
 7 private Bitmap btn_maxImg = ImageObject.GetResBitmap("FANGSI.UI.Images.FormImages.btn_max.png");
 8 private Bitmap btn_miniImg = ImageObject.GetResBitmap("FANGSI.UI.Images.FormImages.btn_mini.png");
 9 private Bitmap btn_restoreImg = ImageObject.GetResBitmap("FANGSI.UI.Images.FormImages.btn_restore.png");
10 private Bitmap _BackImg = ImageObject.GetResBitmap("FANGSI.UI.Images.FormImages.background_mainwnd.jpg");
11 private Size oldSize;//记录当前窗口大小
12 private bool _MaximizeBox = true;//是否启用最大化按钮
13 private int _TopHeight = 100;//窗体头部高度
14 //枚举系统按钮状态
15 public enum FormSystemBtn
16 {
17     SystemAll = 0,
18     SystemNo = 1,
19     btn_close = 2,
20     btn_miniAndbtn_close = 3,
21     btn_maxAndbtn_close = 4
22 }
23 #endregion

2、构建方法,主要将窗体消息的处理以及按钮位置等信息进行设置

  1 #region 方法
  2 protected void SystemBtnSet()
  3 {
  4     int btnTop = 0;
  5     int btnRight = 6;
  6     int panelMargin = 2;
  7     if (WindowState == FormWindowState.Maximized &amp;&amp; FormBorderStyle != System.Windows.Forms.FormBorderStyle.None)
  8     {
  9         btnTop = 10;
 10         btnRight = 16;
 11         panelMargin = 10;
 12     }
 13     this.ContentPanel.Location = new Point(panelMargin, _TopHeight);
 14     this.ContentPanel.Size = new Size(ClientRectangle.Width - (panelMargin * 2), ClientRectangle.Height - _TopHeight - panelMargin);
 15 
 16     switch ((int)_FormSystemBtnSet)
 17     {
 18         case 0:
 19             btn_close.BackImg = btn_closeImg;
 20             btn_close.Location = new Point(this.Width - 32, btnTop);
 21             btn_mini.BackImg = btn_miniImg;
 22             btn_mini.Location = new Point(this.Width - 86, btnTop);
 23             btn_max.BackImg = btn_maxImg;
 24             btn_restore.BackImg = btn_restoreImg;
 25             if (WindowState == FormWindowState.Normal)
 26             {
 27                 btn_max.Location = new Point(this.Width - 59, btnTop);
 28                 btn_restore.Location = new Point(this.Width - 59, -22);
 29             }
 30             else
 31             {
 32                 btn_max.Location = new Point(this.Width - 59, -22);
 33                 btn_restore.Location = new Point(this.Width - 59, btnTop);
 34             }
 35             break;
 36         case 1:
 37             btn_close.BackImg = btn_closeImg;
 38             btn_close.Location = new Point(this.Width - 32, -22);
 39             btn_max.BackImg = btn_maxImg;
 40             btn_max.Location = new Point(this.Width - 59, -22);
 41             btn_mini.BackImg = btn_miniImg;
 42             btn_mini.Location = new Point(this.Width - 86, -22);
 43             btn_restore.BackImg = btn_restoreImg;
 44             btn_restore.Location = new Point(this.Width - 59, -22);
 45             break;
 46         case 2:
 47             btn_close.BackImg = btn_closeImg;
 48             btn_close.Location = new Point(this.Width - 32, btnTop);
 49             btn_max.BackImg = btn_maxImg;
 50             btn_max.Location = new Point(this.Width - 59, -22);
 51             btn_mini.BackImg = btn_miniImg;
 52             btn_mini.Location = new Point(this.Width - 86, -22);
 53             btn_restore.BackImg = btn_restoreImg;
 54             btn_restore.Location = new Point(this.Width - 59, -22);
 55             break;
 56         case 3:
 57             btn_close.BackImg = btn_closeImg;
 58             btn_close.Location = new Point(this.Width - 32, btnTop);
 59             btn_max.BackImg = btn_maxImg;
 60             btn_max.Location = new Point(this.Width - 59, -22);
 61             btn_mini.BackImg = btn_miniImg;
 62             btn_mini.Location = new Point(this.Width - 59, 0);
 63             btn_restore.BackImg = btn_restoreImg;
 64             btn_restore.Location = new Point(this.Width - 59, -22);
 65             break;
 66         case 4:
 67             btn_close.BackImg = btn_closeImg;
 68             btn_close.Location = new Point(this.Width - 32, btnTop);
 69             btn_mini.BackImg = btn_miniImg;
 70             btn_mini.Location = new Point(this.Width - 86, -22);
 71             btn_max.BackImg = btn_maxImg;
 72             btn_restore.BackImg = btn_restoreImg;
 73             if (WindowState == FormWindowState.Normal)
 74             {
 75                 btn_max.Location = new Point(this.Width - 59, btnTop);
 76                 btn_restore.Location = new Point(this.Width - 59, -22);
 77             }
 78             else
 79             {
 80                 btn_max.Location = new Point(this.Width - 59, -22);
 81                 btn_restore.Location = new Point(this.Width - 59, btnTop);
 82             }
 83             break;
 84     }
 85 }
 86 
 87 private void WM_NCHITTEST(ref Message m)
 88 {
 89     int wparam = m.LParam.ToInt32();
 90     Point point = new Point(Win32.LOWORD(wparam), Win32.HIWORD(wparam));
 91     point = PointToClient(point);
 92     if (_IsResize)
 93     {
 94         if (point.X &lt;= 8)
 95         {
 96             if (point.Y &lt;= 8)                 m.Result = (IntPtr)Win32.HTTOPLEFT;             else if (point.Y &gt; Height - 8)
 97                 m.Result = (IntPtr)Win32.HTBOTTOMLEFT;
 98             else
 99                 m.Result = (IntPtr)Win32.HTLEFT;
100         }
101         else if (point.X &gt;= Width - 8)
102         {
103             if (point.Y &lt;= 8)                 m.Result = (IntPtr)Win32.HTTOPRIGHT;             else if (point.Y &gt;= Height - 8)
104                 m.Result = (IntPtr)Win32.HTBOTTOMRIGHT;
105             else
106                 m.Result = (IntPtr)Win32.HTRIGHT;
107         }
108         else if (point.Y &lt;= 8)         {             m.Result = (IntPtr)Win32.HTTOP;         }         else if (point.Y &gt;= Height - 8)
109             m.Result = (IntPtr)Win32.HTBOTTOM;
110         else
111             m.Result = (IntPtr)Win32.HTCAPTION;
112     }
113     else
114     { m.Result = (IntPtr)Win32.HTCAPTION; }
115 }
116 
117 private void btn_close_Click(object sender, EventArgs e)
118 {
119     this.Close();
120 }
121 
122 private void btn_mini_Click(object sender, EventArgs e)
123 {
124     Win32.PostMessage(base.Handle, Win32.WM_SYSCOMMAND, Win32.SC_MINIMIZE, 0);
125 }
126 
127 private void btn_max_Click(object sender, EventArgs e)
128 {
129     Win32.PostMessage(base.Handle, Win32.WM_SYSCOMMAND, Win32.SC_MAXIMIZE, 0);
130 }
131 
132 private void btn_restore_Click(object sender, EventArgs e)
133 {
134     Win32.PostMessage(base.Handle, Win32.WM_SYSCOMMAND, Win32.SC_RESTORE, 0);
135 }
136 
137 private void btn_close_MouseEnter(object sender, EventArgs e)
138 {
139     toolTip1.SetToolTip(btn_close, "关闭");
140 }
141 
142 private void btn_max_MouseEnter(object sender, EventArgs e)
143 {
144     toolTip1.SetToolTip(btn_max, "最大化");
145 }
146 
147 private void btn_mini_MouseEnter(object sender, EventArgs e)
148 {
149     toolTip1.SetToolTip(btn_mini, "最小化");
150 }
151 
152 private void btn_restore_MouseEnter(object sender, EventArgs e)
153 {
154     toolTip1.SetToolTip(btn_restore, "还原");
155 }
156 #endregion

3、属性定义以及方法重写,将扩展属性和窗体重绘等方法结合上一篇的基础类库进行处理

  1 #region 重写方法
  2 protected override void OnInvalidated(InvalidateEventArgs e)
  3 {
  4     base.OnInvalidated(e);
  5 }
  6 
  7 //重绘窗口
  8 protected override void OnPaint(PaintEventArgs e)
  9 {
 10     try
 11     {
 12         g = e.Graphics;
 13         g.SmoothingMode = SmoothingMode.HighQuality; //高质量
 14         g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量
 15         ImageDrawRect.DrawRect(g, ClientRectangle, base.BackColor, _TopHeight);//绘制白色内容区域
 16         Brush brush = new SolidBrush(Color.White);//定义画笔
 17         PointF point = new PointF(10, 10);//定义标题显示坐标
 18         Font TitleFont = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
 19         g.DrawString(base.Text, TitleFont, brush, point.X, point.Y);
 20 
 21     }
 22     catch
 23     { }
 24 }
 25 
 26 //重载WndProc方法
 27 protected override void WndProc(ref Message m)
 28 {
 29     try
 30     {
 31         switch (m.Msg)
 32         {
 33             //用户选择最大化按钮,最小化按钮,复原按钮或关闭按钮时,窗口将会接收该消息
 34             case Win32.WM_SYSCOMMAND:
 35                 #region
 36                 if ((m.WParam != (IntPtr)Win32.SC_MAXIMIZE) &amp;&amp; (m.WParam.ToInt32() != 0xf032))
 37                 {
 38                     if ((m.WParam == (IntPtr)Win32.SC_RESTORE) || (m.WParam.ToInt32() == 0xf122))
 39                     {
 40                         base.Size = this.oldSize;
 41                     }
 42                     else if ((m.WParam == (IntPtr)Win32.SC_MINIMIZE) || (m.WParam.ToInt32() == 0xf022))
 43                     {
 44                         if (this.oldSize.Width == 0)
 45                         {
 46                             this.oldSize = base.Size;
 47                         }
 48                     }
 49                     break;
 50                 }
 51                 this.oldSize = base.Size;
 52 
 53                 #endregion
 54                 break;
 55             //在需要计算窗口客户区的大小和位置时发送。通过处理这个消息,应用程序可以在窗口大小或位置改变时控制客户区的内容
 56             case Win32.WM_NCCALCSIZE:
 57             //窗体客户区以外的重绘消息,一般是由系统负责处理
 58             case Win32.WM_NCPAINT:
 59                 return;
 60             //鼠标移动,按下或释放都会执行该消息
 61             case Win32.WM_NCHITTEST:
 62                 WM_NCHITTEST(ref m);
 63                 return;
 64             //画窗体被激活或者没有被激活时的样子
 65             case Win32.WM_NCACTIVATE:
 66                 #region
 67                 if (m.WParam == (IntPtr)Win32.WM_FALSE)
 68                 {
 69                     m.Result = (IntPtr)Win32.WM_TRUE;
 70                 }
 71                 #endregion
 72                 return;
 73             default:
 74                 base.WndProc(ref m);
 75                 return;
 76         }
 77         base.WndProc(ref m);
 78     }
 79     catch { }
 80 }
 81 
 82 private void BaseForm_Resize(object sender, EventArgs e)
 83 {
 84     SystemBtnSet();
 85 }
 86 
 87 protected override void OnResizeEnd(EventArgs e)
 88 {
 89     base.OnResizeEnd(e);
 90     this.oldSize = base.Size;
 91 }
 92 
 93 ///
 94 /// 重写标题属性
 95 ///
 96 public override string Text
 97 {
 98     set
 99     {
100         if (value != base.Text)
101         {
102             base.Text = value;
103             this.Invalidate();
104         }
105     }
106     get
107     {
108         return base.Text;
109     }
110 }
111 #endregion

3、窗体属性的定义

 1 #region 属性
 2 
 3 [DefaultValue(true)]
 4 [CategoryAttribute("放肆雷特皮肤扩展属性"), Description("是否允许改变窗口大小")]
 5 public bool IsResize
 6 {
 7     get { return this._IsResize; }
 8     set { _IsResize = value; }
 9 }
10 
11 [DefaultValue(true)]
12 [CategoryAttribute("放肆雷特皮肤扩展属性"), Description("是否在右上角显示最大化按钮")]
13 public new bool MaximizeBox
14 {
15     get
16     {
17         return base.MaximizeBox;
18     }
19     set
20     {
21         base.MaximizeBox = value; this.btn_max.Enabled = value;
22     }
23 }
24 
25 [CategoryAttribute("放肆雷特皮肤扩展属性"), Description("系统按钮设置")]
26 public FormSystemBtn FormSystemBtnSet
27 {
28     get
29     {
30         return _FormSystemBtnSet;
31     }
32     set
33     {
34         _FormSystemBtnSet = value;
35         this.Invalidate();
36 
37     }
38 }
39 
40 [CategoryAttribute("放肆雷特皮肤扩展属性"), Description("获取或设置窗体图标")]
41 public new Icon Icon
42 {
43     get
44     {
45         return base.Icon;
46     }
47     set
48     {
49         if (value != base.Icon)
50         {
51             base.Icon = value;
52             this.Invalidate();
53         }
54 
55     }
56 }
57 
58 [CategoryAttribute("放肆雷特皮肤扩展属性"), Description("获取或设置窗体头部高度"), DefaultValue(100)]
59 public new int TopHeight
60 {
61     get
62     {
63         return _TopHeight;
64     }
65     set
66     {
67         _TopHeight = value;
68         this.Invalidate();
69 
70     }
71 }
72 #endregion

4、窗体构造函数中窗体样式以及动作进行初始化设置

 1 #region 构造函数
 2 public BaseForm()
 3 {
 4     InitializeComponent();
 5     this.SetStyle(ControlStyles.UserPaint, true);//自绘
 6     this.SetStyle(ControlStyles.DoubleBuffer, true);// 双缓冲
 7     this.SetStyle(ControlStyles.ResizeRedraw, true);//调整大小时重绘
 8     this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
 9     this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);// 双缓冲
10     this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);   //透明效果
11     if (this.BackgroundImage == null)
12     {
13         this.BackgroundImage = _BackImg;
14     }
15     SystemBtnSet();
16 }
17 #endregion

使用的时候只需要在窗体中继承这个窗体就可以使用窗体的风格了!下面是效果图:

进行到这里窗体和按钮结合的窗体就已经出来了,中间的背景图片是从360安全卫士提取出来的资源中拿到的。如果还有不懂的欢迎进行留言提问。下一篇就开始将文本框的制作敬请期待喔。。


本文来自 放肆雷特 | 胖子的技术博客

转载于:https://www.cnblogs.com/kovin/p/3240305.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/a_18291513321/article/details/102430059

智能推荐

Struts2 + Pluto + portletV1.0(JSR 168) CRUD Demo_Z_ZW的博客-程序员宅基地

2009年12月3號 Struts2.1.8.1 + Pluto1.1.7 + portletV1.0(JSR 168) CRUD Demo(20091203止)本來想用portlet2.0(JSR 268)整合Struts2的,但是Struts2的最新版的Portlet插件JAR包也僅僅支持JSR 168規範,所以只能退回去用戶JSR168了。。。 由於Pluto1.X系列和...

机器学习库sklearn学习总结_辣大辣条的博客-程序员宅基地

https://blog.csdn.net/fuqiuai/article/details/79495865常用模块sklearn中常用的模块有分类、回归、聚类、降维、模型选择、预处理。分类:识别某个对象属于哪个类别,常用的算法有:SVM(支持向量机)、nearest neighbors(最近邻)、random forest(随机森林),常见的应用有:垃圾邮件识别、图像识别。回归:...

阿里云上部署Rstudio Server以及Shiny Server_鲜-橙的博客-程序员宅基地

Rstudio Server根据rstudio官网的步骤进行部署我的系统是Ubuntu 16.04,因此选ubuntu,其中要选择32位还是64位的时候,可以在自己的服务器键入下面的命令查看自己的系统架构 uname -a部署完之后创一个非root账号 useradd your_account -m -s /bin/bash sudo passwd linc...

java class文件比较_Beyound Compare中比较java字节码class文件_Rachel G33的博客-程序员宅基地

背景项目维护的时候版本混乱或者外出在现场项目排错的时候难免要比对两个jar/class/war文件的源代码。通常情况下这个时候我们用jd-gui直接把文件拖进去比对,这种情况只适合单一文件的比对。如果一个lib目录下有很多jar或者class文件要比对,这个时候工作量就比较大了。笔者去年这个时候在网络上研究了一番,找到了一个可以批量反编译的中间件,后来写了一遍文章CFR - another jav...

如何使用Mabatis操作数据库_黄小强-Roland的博客-程序员宅基地

参考mybatis文档第一步:数据库的准备,以mysql为例。CREATE DATABASE mybatis;USE mybatis;CREATE TABLE USER(id INT(11) AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) DEFAULT NULL,psw VARCHAR(50) DEFAULT NULL)ENGIN...

【代码片段】序列化和反序列化之对象基类_SZ大伟的博客-程序员宅基地

/// &amp;lt;summary&amp;gt; /// 支持序列化的对象基类 /// &amp;lt;/summary&amp;gt; [Serializable] public class LibSerializationObject : ISerializable, IDeserializationCallback { #region 构造函数 ...

随便推点

vue项目提交到github_执着的雨的博客-程序员宅基地

前提: 配置git、以及git的ssh key信息假设已经都安装好了在项目目录 初始化本地仓库,会创建一个.git目录 git init 将项目所有文件(未被ignore)添加到仓库 git add .将add文件提交到本地仓库 git commit -m ‘提交信息’本地仓库关联远程git仓库 git remote add origin git仓库本地仓库代码提交到服务器 g

培训课程_punmpkin的博客-程序员宅基地

https://www.w3cschool.cn/tutorial

svn常用命令行和批处理_magictong的博客-程序员宅基地

      在进行大量svn更新和多个工程联合编译时,如果是对你来说是一件经常重复做的事情,譬如更新代码编译版本;更新代码,编译版本并升级之类的重复性很高,枯燥而且容易出错的事情,使用批处理来统一管理和处理将大大简化工作流程,使编版本,升级成为一件快乐的事情,想一下,要升级了,准备工作做好后,运行下批处理,“哗哗”就跟你有条不紊的做好了,多么惬意的一件事情,而且不可能产生人为原因的错误,要统一批处

如何将Hexo Blog同时发布到GitHub跟Coding上_hero的技术小黑屋的博客-程序员宅基地_hexo怎么配置公钥

前言上一篇文章已经讲过怎样使用Hexo建立博客以及怎样将Hexo博客发布到GitHub上.如果对Hexo建立博客还不熟悉请先看看之前的那篇文章我的Hexo博客建站日志.大家可能跟我一样,建站的时候很轻松,但是等往github上提交的时候会等待很长时间,毕竟GitHub是国外的东西,很多地方会被墙掉,在我们现在不翻墙的情况下如何能将自己的博客迅速的托管到免费平台上呢?于是我想到了我比较喜欢保存自己项目

Python错误总结:因Pandas版本问题造成时间戳‘Timestamp‘报错问题_我爱学习很果断!的博客-程序员宅基地

在利用某股票数据绘图时报错:TypeError: float() argument must be a string or a number, not ‘Timestamp’在使用某股票的日收盘价数据绘制其波动率走势图时,同样的代码,朋友可以用Python的Spyder正常运行并输出所需要的图片,我使用Jupyter运行代码时却报出如下错误:查找发现是因为Pandas版本问题,只需在绘图前加入以下代码便可解决问题:&gt;&gt;&gt;pd.Timestamppd.Periodnp.datet

【解决】ThinkPad X1 Carbon安装Ubuntu 16.04没有WiFi的问题_mainking2003的博客-程序员宅基地_thinkpadx1 carbon ubuntu

设备:ThinkPad X1 Carbon,无线网卡Intel Wireless AC 9560 160MHz系统:Windows10,Ubuntu16.04.6问题:安装Ubuntu后没有WiFi解决方法:安装Ubuntu下的Intel 9560驱动关闭电脑启动时的secure boot链接网线,按如下步骤安装:sudo apt updatesudo apt install git build-essentialgit clone https://git.kernel.org

推荐文章

热门文章

相关标签