我正在创建一个在Winforms应用程序中使用的小模式窗体.它基本上是各种进度条.但我希望用户能够单击表单中的任意位置并拖动它以在桌面仍在显示时在桌面上移动它.
我该如何实现这种行为?
Microsoft知识库文章320687对此问题有详细解答.
基本上,当正在测试的点位于表单的客户区域时,您覆盖WndProc方法将HTCAPTION返回到WM_NCHITTEST消息 - 这实际上告诉Windows将点击处理完全相同表格的标题.
private const int WM_NCHITTEST = 0x84; private const int HTCLIENT = 0x1; private const int HTCAPTION = 0x2; protected override void WndProc(ref Message m) { switch(m.Msg) { case WM_NCHITTEST: base.WndProc(ref m); if ((int)m.Result == HTCLIENT) { m.Result = (IntPtr)HTCAPTION; } return; } base.WndProc(ref m); }
这是使用P/Invoke执行此操作的方法.
public const int WM_NCLBUTTONDOWN = 0xA1; public const int HTCAPTION = 0x2; [DllImport("User32.dll")] public static extern bool ReleaseCapture(); [DllImport("User32.dll")] public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); void Form_Load(object sender, EventArgs e) { this.MouseDown += new MouseEventHandler(Form_MouseDown); } void Form_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { ReleaseCapture(); SendMessage(Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0); } }