Winforms - 用于单击控件的WM_NCHITEST消息

时间:2012-09-12 15:57:08

标签: c# .net winforms wndproc

我有一个没有边框的简单窗体和几个标签控件(不需要点击任何内容)。我需要允许用户通过单击任何位置来移动表单,因此我找到了this问题,并使用了以下代码。

    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;
                } else {
                    return;
                }
                break;
        }
        base.WndProc(ref m);            
    }

这很有效......到了一定程度。如果我点击表单本身的任何位置(背景),WM_NCHITTESTHTCLIENT,那么我可以按预期移动表单。但是,如果我单击一个标签控件本身,该消息就会有所不同,我无法分辨它是什么。

我找到this article关于WM_NCHITTEST的各种可能值,但它们似乎都不是我需要的。

我意识到我可以禁用所有标签控件,这样我就可以点击“on”它们就好像是表单一样,但我想知道是否有更好/不同的方法来执行此操作。

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

您正在覆盖表单的WndProc,但当光标位于标签上时,WM_NCHITTEST消息将发送到标签。

您可以创建自己的Label标签控件并覆盖其WndProc。这应始终返回HTTRANSPARENT以响应WM_NCHITTEST。类似的东西:

private const int HTTRANSPARENT = -1;

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case WM_NCHITTEST:
            m.Result = (IntPtr)HTTRANSPARENT;
            return;
    }
    base.WndProc(ref m);
}

另请注意,WndProc中存在一个小错误。如果邮件为WM_NCHITTEST但该区域不是HTCLIENT,那么您将两次调用基类。