前言
话说鼠标点击客户区域实现移动窗体蛮简单的,目前有3种方法。
1.通过Form的MouseDown、MouseMove、MouseUp实现。这个逻辑比较简单就不介绍了。
2.通过Form的MouseDown事件里调用API。主要是调用ReleaseCapture()及SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0),WM_SYSCOMMAND=0x112、SC_MOVE=0xf010、HTCAPTION=0x2。大概是这样,有兴趣的可以试试。
3.重写WndProc函数,处理WM_NCHITTEST消息。
我是懒得用API,就选了第三种实现。
实现
先看代码,对WM_NCHITTEST消息有兴趣可以看看这里,以及MSDN。
protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == 0x84) //WM_NCHITTEST { m.Result = (IntPtr)2; //HTCAPTION } }
问题1
坑爹的是,Form在无边框的时候,双击工作区就最大化,把屏幕的工具栏区域也覆盖了。
好吧,在构造函数里加句this.MaximumSize = Screen.PrimaryScreen.WorkingArea.Size;
问题2
最大化没问题了,但是你丫最大化了还能移动就太二了吧。
想想就只能在处理Windows消息之前把鼠标左键点击消息屏蔽了。
完整代码如下:
protected override void WndProc(ref Message m) { if (this.Size.Equals(this.MaximumSize)) { if (m.Msg == 0xA1) //WM_NCLBUTTONDOWN return; } base.WndProc(ref m); if (m.Msg == 0x84) //WM_NCHITTEST { m.Result = (IntPtr)2; //HTCAPTION } }