• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#自定义窗体(不设置FormBorderStyle=none)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一直以来都在自定义窗体上困惑 从最初的把边框隐藏,到使用位图,处理消息支持窗体的拖动等,总是不太理想。因为以前都是将FormBorderStyle设置为none 这样窗体就真的没有系统边框了,这也带来了一些问题 一旦把FormBorderStyle设置为none就等于去掉了窗体的非客户区 系统也就认为窗体是没有边框的,当然这样的窗体也失去了系统指令 具体表现在Windows7上,系统主题让窗体在最大化最小化的时候都有动画效果,打开和关闭窗体的时候也有淡入淡出的效果 一旦把FormBorderStyle设置为none这些效果都将失去

经过一段时间之后 终于明白了怎么保留这些效果的同时又可以让客户区的大小等于整个窗体的大小

现在说说解决这个问题的方法

当窗体实例化之后我们需要处理相关的消息 拦截非客户区的消息

具体是这几个WM_NCPAINT WM_NCCALCSIZE WM_NCACTIVATE WM_NCHITTEST

对于前3个消息我们不做处理 对于WM_NCHITTEST 通过处理它我们支持窗体的移动 上下左右以及四个角的拖动大小操作

这是仿QQ2010的窗体 由于客户区大小等于窗体大小 所以最大化最小化关闭按钮可以定义控件放到右上角去 这里主要介绍实现这个窗体的关键

 

代码
 1 protected override void WndProc(ref Message m)
 2 {
 3     if (m.Msg == Win32.WM_NCPAINT)
 4     {
 5         return;
 6     }
 7     else if (m.Msg == Win32.WM_NCCALCSIZE)
 8     {
 9         return;
10     }
11     else if (m.Msg == Win32.WM_NCACTIVATE)
12     {
13         if (m.WParam == (IntPtr)Win32.WM_FALSE)
14         {
15             m.Result = (IntPtr)Win32.WM_TRUE;
16         }
17     }
18     else if (m.Msg == Win32.WM_NCHITTEST)
19     {
20         if (_canResize == true)
21         {
22             Point point = new Point(m.LParam.ToInt32());
23             int x = point.X;
24             int y = point.Y;
25             if (x < this.Left + 11 && y < this.Top + 11)
26             {
27                 m.Result = (IntPtr)Win32.HTTOPLEFT;
28             }
29             else if (x > this.Right - 11 && y < this.Top + 11)
30             {
31                 m.Result = (IntPtr)Win32.HTTOPRIGHT;
32             }
33             else if (x > this.Right - 11 && y > this.Bottom - 11)
34             {
35                 m.Result = (IntPtr)Win32.HTBOTTOMRIGHT;
36             }
37             else if (x < this.Left + 11 && y > this.Bottom - 11)
38             {
39                 m.Result = (IntPtr)Win32.HTBOTTOMLEFT;
40             }
41             else if (x < this.Left + 9)
42             {
43                 m.Result = (IntPtr)Win32.HTLEFT;
44             }
45             else if (y < this.Top + 9)
46             {
47                 m.Result = (IntPtr)Win32.HTTOP;
48             }
49             else if (x > this.Right - 9)
50             {
51                 m.Result = (IntPtr)Win32.HTRIGHT;
52             }
53             else if (y > this.Bottom - 9)
54             {
55                 m.Result = (IntPtr)Win32.HTBOTTOM;
56             }
57             else
58             {
59                 m.Result = (IntPtr)Win32.HTCAPTION;
60             }
61 
62         }
63         else
64         {
65             //m.Result = (IntPtr)Win32.HTCAPTION;
66             ReleaseCapture();
67             SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + Win32.HTCAPTION, 0);
68 
69         }
70     }
71     else
72         base.WndProc(ref m);
73 }

 

 

经过这样的处理之后非客户区依然存在 只是没有了尺寸,使得窗体的大小和非客户区一样了 这里处理拖动的那部分比如边框+9 -9实际上是+ -4 ,因为我把窗体的有效区域的宽度和高度都设置为比窗体小10 事实上QQ的窗体大小和有效区域也是上下左右各5像素的偏差,这样最有一个好处 就是在最大化的时候 当窗体充满屏幕的时候 基本上标题栏这些基本全部能看见

当然这不属于关键的地方  做好这些之后再给窗体设计一些丰富的属性 作为基窗体使用,非常具有实用的价值


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#KeepAlive的设置发布时间:2022-07-10
下一篇:
接口C#请求数据模拟POST发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap