首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Winforms -在窗体中的任意位置单击/拖动以移动它,就像在窗体标题中单击一样

Winforms -在窗体中的任意位置单击/拖动以移动它,就像在窗体标题中单击一样
EN

Stack Overflow用户
提问于 2008-08-27 13:59:01
回答 4查看 13K关注 0票数 19

我正在创建一个小的模态表单,用于Winforms应用程序。它基本上是一种进度条。但我希望用户能够在窗体中的任何地方单击并拖动它,以便在桌面上移动它,同时它仍在显示。

如何实现此行为?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2008-08-27 14:16:51

Microsoft KB Article 320687对这个问题有一个详细的答案。

基本上,当要测试的点位于窗体的工作区时,您可以重写WndProc方法以将HTCAPTION返回到WM_NCHITTEST消息--这实际上是告诉Window将单击完全视为发生在窗体标题上的单击。

代码语言:javascript
复制
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);
}
票数 26
EN

Stack Overflow用户

发布于 2008-08-27 14:29:06

以下是使用P/Invoke完成此操作的一种方法。

代码语言:javascript
复制
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);
    }
}
票数 15
EN

Stack Overflow用户

发布于 2014-02-01 01:20:21

公认的答案是一个很酷的技巧,但是如果窗体被一个填充停靠的子控件覆盖,例如Panel (或派生的),它并不总是有效,因为这个控件将吃掉所有的Windows消息。

这里有一个简单的方法,也适用于这种情况:派生有问题的控件(使用这个类而不是标准的),并像这样处理鼠标消息:

代码语言:javascript
复制
    private class MyTableLayoutPanel : Panel // or TableLayoutPanel, etc.
    {
        private Point _mouseDown;
        private Point _formLocation;
        private bool _capture;

        // NOTE: we cannot use the WM_NCHITTEST / HTCAPTION trick because the table is in control, not the owning form...
        protected override void OnMouseDown(MouseEventArgs e)
        {
            _capture = true;
            _mouseDown = e.Location;
            _formLocation = ((Form)TopLevelControl).Location;
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            _capture = false;
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (_capture)
            {
                int dx = e.Location.X - _mouseDown.X;
                int dy = e.Location.Y - _mouseDown.Y;
                Point newLocation = new Point(_formLocation.X + dx, _formLocation.Y + dy);
                ((Form)TopLevelControl).Location = newLocation;
                _formLocation = newLocation;
            }
        }
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档