移动窗体没有标题栏窗体、标题栏

2023-09-06 11:05:04 作者:听风祭雨

我有没有标题栏的窗口形式。我想通过鼠标拖动它。搜索在互联网上之后,我发现这个code移动方式:

I have a windows form without title bar. I want to drag it by mouse. After searching on internet, I found this code for moving form:

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case 0x84:
            base.WndProc(ref m);
            if ((int)m.Result == 0x1)
                m.Result = (IntPtr)0x2;
            return;
    }
base.WndProc(ref m);
}

但它有一个问题:它只能运行在其上并不受任何控制窗体区域。例如,如果我使用的标签或组框,我无法通过点击移动形式。 我该如何解决这个问题呢?

But it has a problem: It operates only on form regions which are not covered by any control. For example if I use label or group box, I can't move form by clicking on them. How can I solve this problem?

推荐答案

一个办法是实施 IMessageFilter 是这样的。

One way is to implement IMessageFilter like this.

public class MyForm : Form, IMessageFilter
{
    public const int WM_NCLBUTTONDOWN = 0xA1;
    public const int HT_CAPTION = 0x2;
    public const int WM_LBUTTONDOWN = 0x0201;

    [DllImportAttribute("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    [DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();

    private HashSet<Control> controlsToMove = new HashSet<Control>();

    public MyForm()
    {
        Application.AddMessageFilter(this);

        controlsToMove.Add(this);
        controlsToMove.Add(this.myLabel);//Add whatever controls here you want to move the form when it is clicked and dragged
    }

    public bool PreFilterMessage(ref Message m)
    {
       if (m.Msg == WM_LBUTTONDOWN &&
            controlsToMove.Contains(Control.FromHandle(m.HWnd)))
        {
            ReleaseCapture();
            SendMessage(this.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            return true;
        }
        return false;
    }
}