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

技术标签: 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

智能推荐

DevExpress 自定义GridControl_devexpress.xtragrid.views.grid.viewinfo.gridviewin-程序员宅基地

文章浏览阅读472次。DevExpress 自定义GridControl代码结构代码如下:代码结构代码如下:using System;using System.Collections.Generic;using System.Linq;using System.Text;using DevExpress.XtraGrid.Views.Grid;using DevExpress.XtraGrid;us..._devexpress.xtragrid.views.grid.viewinfo.gridviewinfo.updatecellappearance(gr

linux下/dev/tty, /dev/tty0, /dev/console区别-程序员宅基地

文章浏览阅读1.7w次,点赞6次,收藏23次。转自 http://blog.chinaunix.net/uid-20727076-id-3062401.html 在我的fedora11系统(linux2.6.31)下,这三个设备的具体情况如下:[root@localhost dev]# ls -l ttycrw-rw-rw- 1 root tty 5, 0 2012-01-30 17:26 tty[root@loc_/dev/tty

论程序员成长的正确姿势,下载量瞬秒百万-程序员宅基地

文章浏览阅读65次。个人背景如标题所示,我的个人背景非常简单,Java开发经验1年半,学历普通,2本本科毕业,毕业后出来就一直在Crud,在公司每天重复的工作对我的技术提升并没有什么帮助,但小镇出来的我也深知自我努力的重要性,想要改变“命运”,没有背景没有资本的人,只能通过勤奋获得。幸运女神往往会眷顾努力的人,所以当好运降临到我头上,我并不诧异,目前拿到了美团30K的offer,下文也不说废话,主要分享我这次“美团面试经历”和“个人学习方法”,希望能帮助到你们。蚂蚁金服一面:分布式架构 50分钟个人介绍加项目介绍2

Qt_常用控件_Table Widget_qt tablewidget-程序员宅基地

文章浏览阅读1.7w次,点赞19次,收藏170次。Qt_常用控件_tablewidget_qt tablewidget

spring整合mybatis异常 UnsatisfiedDependencyException BeanCreationException PropertyBatchUpdateException_unsatisfied dependency expressed through field 'st-程序员宅基地

文章浏览阅读1k次。Spring整合mybats引发异常对于自己无知的记录(浪费了一天)事发现场org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘studentInfoServiceImpl’: Unsatisfied dependency expressed through field ‘studentInfoMapper’; nested exception is org.sp_unsatisfied dependency expressed through field 'studentmapper'; nested excep

Springboot集成rabbitmq实现延时队列_rabbit mq 有时间轮吗-程序员宅基地

文章浏览阅读326次。Springboot集成rabbitmq实现延时队列什么是延时队列?列举几个使用场景:常见的种类有:延时任务-实现方式:详细信息:[https://www.cnblogs.com/JonaLin/p/11550427.html](https://mp.csdn.net).RabbitMQ-延时任务RabbitMQ TTL和DXL延时队列实现方案:源码地址:[https://github.com/9..._rabbit mq 有时间轮吗

随便推点

svg中fill-rule属性解析_svg fill-rule-程序员宅基地

文章浏览阅读1.8w次,点赞4次,收藏5次。fill-rule属性规定了svg图形的填充规则 fill-rule 有效值 nonzero / evenodd / inherit 默认值 nonzero 应用于 shape形状类元素和文字内容类元素 可继承 是 比例 无 媒体 可见 动画可用 是fill-rule属性用于指定使用哪一种短发去判断画布上的某区域是否属于该图形的“内部_svg fill-rule

使用div和js脚本弹出对话框_js 弹出div对话框-程序员宅基地

文章浏览阅读2.9k次。使用div和js脚本弹出一个对话框思路:div已经存在于网页当中,只是被隐藏了,当点击按钮时将其可见性设置为可见即可实现实现:在网页中设置好需要弹出的窗口,为其他控件设置一个事件,当触发该事件时将窗口设置为可见控件_js 弹出div对话框

Lucenesolr_lucene-solr-程序员宅基地

文章浏览阅读245次。Lucene全文检索技术课程计划Lucene介绍 全文检索流程介绍 索引流程 搜索流程 Lucene入门程序 索引实现 搜索实现 分词器 分词介绍 IK分词器 搜索技术理论基础 为什么要学习Lucene 原来的方式实现搜索功能,我们的搜索流程如下图:正在上传…重新上传取消正在上传…重新上传取消上图就是原始搜索引擎技术,如果用户比较少而且数据库的数据量比较小,那么这种方式实现搜索功能在企业中是比较常见..._lucene-solr

ios appstore 上架应用被拒绝原因_ios上架苹果商店提示支付宝支付,拒绝上架-程序员宅基地

文章浏览阅读1.5w次。http://blog.csdn.net/annkey123/article/details/8778996_ios上架苹果商店提示支付宝支付,拒绝上架

linux基础入门指令详解_已知有目录结构如图:已知当前工作目录为d1,要将文件f1移动到目录d2下,正确的命令-程序员宅基地

文章浏览阅读201次。Linux有150个常用指令,透过12道题去学习以及练习指令1、创建一个目录/dzqc提示: windows下的路径样式为c: \dzqc\ test,而linux下的路径样式为 /dzqc/test因此/dzqc就可以看做是c:\dzqc,不同的是 windows系统下还有D,E等盘, linux下就只有/为所有目录的顶点。英文 make directorys缩写后就是 mkdir,这..._已知有目录结构如图:已知当前工作目录为d1,要将文件f1移动到目录d2下,正确的命令

2021/3/27 每周总结-程序员宅基地

文章浏览阅读51次。每周总结1.学习总结有的题目可以转变思维来简化问题,比如vjudge上的那个骑车子的那个问题,要找最快到达终点的时间,可以直接找出最快的车辆算出最快的时间,而不必去模拟这道题的过程以简化问题,已经遇到了很多到和这种思想类似的题目,还有雷达那道题目(现在还没弄懂QAQ)也是有这种类似的思想,把范围由二维转化成一维。这种转化的思想可以把问题变得更简单,但就是有点难想。。。2.学习感受这周主要内容还是贪心,有的题目还是有一定难度的,想上半天想不出思路,感觉还是自己刷的题少,在周四的比赛中就明显的显露出来,