winforms 移动不带标题栏的窗体

g0czyy6m  于 2022-11-17  发布在  其他
关注(0)|答案(5)|浏览(153)

我有一个没有标题栏的windows窗体。我想用鼠标拖动它。在网上搜索后,我发现了移动窗体的代码:

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);
}

但它有一个问题:它仅在未被任何控件覆盖窗体区域上起作用例如,如果使用标签或分组框,则无法通过单击来移动窗体
我怎样才能解决这个问题?

dfty9e19

dfty9e191#

一种方法是像这样实现IMessageFilter

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;
    }
}
e4eetjau

e4eetjau2#

这基本上就是您希望做的事情:
Make a borderless form movable?
您可以将相同的程式码加入至表单上其他控件的鼠标器按下事件,以完成相同的工作。

thigvfpy

thigvfpy3#

Make a borderless form movable?

public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;

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

private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{     
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
    }
}
w8biq8rn

w8biq8rn4#

当用户在窗体中的lblMoveForm Label上按下鼠标时,将执行以下事件处理程序。

// On left button, let the user drag the form.
private void lblMoveForm_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        // Release the mouse capture started by the mouse down.
        lblMoveForm.Capture = false; //select control

        // Create and send a WM_NCLBUTTONDOWN message.
        const int WM_NCLBUTTONDOWN = 0x00A1;
        const int HTCAPTION = 2;
        Message msg =
            Message.Create(this.Handle, WM_NCLBUTTONDOWN,
                new IntPtr(HTCAPTION), IntPtr.Zero);
        this.DefWndProc(ref msg);
    }
}
xbp102n0

xbp102n05#

//For base form moving
private const int HT_CAPTION = 0x2;
private const int WM_NCHITTEST = 0x84;
private const int HT_CLIENT = 0x1;

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    if (m.Msg == WM_NCHITTEST)
        m.Result = (IntPtr)(HT_CAPTION);
}

//For any component you also want use to move form
private bool arrastando= false;
private Point pontoinicial= new Point(0,0);
private Point meu_offset;

//use this method for component event called MouseDown
private void dragMouseDown(object sender, MouseEventArgs e)
{
    arrastando = true;
    pontoinicial = new Point(e.X, e.Y);
}
//use this method for component event called MouseUp
private void dragMouseUp(object sender, MouseEventArgs e)
{
    arrastando=false;
}
//use this method for component event called MouseMove
private void dragMouseMove(object sender, MouseEventArgs e)
{
    if (arrastando)
    {
    Point p = PointToScreen(e.Location);
    ActiveForm.Location = new Point(p.X - this.pontoinicial.X,
                                    p.Y - this.pontoinicial.Y);
    }
}

相关问题