【问题标题】:Moving Form without title bar移动没有标题栏的表格
【发布时间】:2014-07-20 21:38:18
【问题描述】:

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

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

但它有一个问题:它只在不受任何控件覆盖的表单区域上运行。例如,如果我使用标签或组框,我无法通过单击它们来移动表单。
我该如何解决这个问题?

【问题讨论】:

  • 您确定要在用户单击控件时让单击并拖动表单工作吗?单击然后变得模棱两可,用户是否尝试对控件执行某些操作?可能最好接受你现在的工作方式。
  • 不适用于所有控件。我只想将它用于看起来像表单背景的控件,如标签、组框、面板、矩形形状,...
  • 表单有边框是有原因的。只需使用标准边框。用户不会期望能够单击并拖动控件来移动表单。
  • @Hamid:我不同意 - 标签看起来不像 chrome(背景)。组框也没有。面板和矩形可能会也可能不会,但在顶部留下足够的背景就足够了!对于某些特殊情况,您可能需要添加上述代码,但用户不希望在单击并拖动标签时移动窗口。
  • 我同意你的看法。我在表单顶部留下了足够的背景空间以及该区域的标题标签。我希望用户在单击标签(标题栏)时可以移动表单。

标签: c# .net winforms


【解决方案1】:

这基本上就是你想要做的:

Make a borderless form movable?

您也许可以将相同的代码添加到表单上其他控件的鼠标按下事件以完成相同的事情。

【讨论】:

  • 这段代码也有我的问题中提到的问题。我无法通过点击标签和面板来移动表单。
  • 您是否尝试将相同的代码添加到这些标签和面板的鼠标按下事件中?
  • 如果将处理程序添加到表单控件,请确保在发送消息时使用表单的句柄。
【解决方案2】:

一种方法是像这样实现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;
    }
}

【讨论】:

  • Application.AddMessageFilter(this); 抛出错误
【解决方案3】:

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

【讨论】:

  • 这比所有其他解决方案都好,因为它没有添加太多样板代码
【解决方案4】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-27
    • 2018-07-10
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多