C# 禁用 click/doubleClick 或任何 WindowsMessage

C# Disable click/doubleClick or any WindowsMessage

我的目标是禁用我的应用程序中的所有 DoubleClick() 事件。只是简单地取消订阅这些事件是不可能的,因为那些是外部自定义控件。所以我的目标是为这些控件或我的整个应用程序禁用 DoubleClick(),这并不重要。

我想做的是一旦 window 收到 WindowsMessage WM 并且 ID 号 Message.Msg 是例如Button.Click() 事件。

private const int WM_COMMAND = // ???

if (m.Msg == WM_COMMAND)
    ...

但是无论我使用哪种 WindowsMessage 通知代码,我都无法得到正确的通知代码,一旦单击控件就会触发该通知代码。但我很高兴在 Form 上对 DoubeClick() 进行干预。

private const int WM_NCLBUTTONDBLCLK = 0x00A3;
private const int WM_LBUTTONDBLCLK = 0x0203;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_NCLBUTTONDBLCLK || m.Msg == WM_LBUTTONDBLCLK)
    {
        m.Result = IntPtr.Zero;
        return;
    }

    base.WndProc(ref m);
}

这完全没问题,并且在客户区和[=21]的非客户区上取消了DoubleClick =].但是当我悬停在控件上时,我定位在哪个区域?因为那些 WindowsMessages 指的是 客户区 非客户区 当我在控件上时不要被触发。


Sent when the user clicks a button. The parent window of the button receives this notification code through the WM_COMMAND message.

MSDN doc about a button click notifaction message

WM_COMMAND 消息具有此通知代码:

private const int WM_COMMAND = 0x0111;

因此,当我尝试对发送的这条消息做出反应时,我做不到,因为这条消息没有被触发。

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_COMMAND)
        MessageBox.Show("foo"); // nothing happens

    base.WndProc(ref m);
}

我对这个 WindowsMessage 遗漏了什么或误解了什么?

因为还没有人发布答案,我在这里找到了一个很好的解决方案,我尝试禁用所有 DoubleClick()s 或仅 one/a 几个想要的 Control/s。

问题是 WndProc() 不过滤或响应正在发送的 所有 WM。因此,无法检测到 非客户区 0x0203 上默认 doubleClickWM。所以我更深入地在 WM 到达 WndProc() 之前过滤它们。一种方法是使用分配给我的 Application.

MessageFilter
private MessageFilter msgFilter = new MessageFilter();

Application.AddMessageFilter(msgFilter);

方法Param是我自己的一个对象classMessageFilter,需要实现IMessageFilter接口才能使用PreFilterMessage()。为发送到您的应用程序的 eachWM 调用此方法。

class MessageFilter : IMessageFilter
{
    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == 0x0203)
        {
            m.Result = IntPtr.Zero;
            return true;
        }
        else
            return false;
    }
}

所以基本上一旦有一个 WM 具有所需的 Message.Msg ID,我将 Result 设置为 zero 所以 DoubleClick() 被完全禁用对于整个应用程序。


后来发现最好只从一个 Control 禁用 DoubleClick()。由于 Windows 中的每个 Control 都有一个唯一的 Handle HWnd,它是 Message 的一部分,如果某个 Message 瞄准了我,我可以用它来扫描具体单曲Control.

当您创建 Control 时,可以在 .Designer.cs 中订阅事件:

this.yourControl.HandleCreated += new System.EventHandler(this.yourControl_HandleCreated);

或者,如果它是自定义 Control,请在事件创建后订阅它。如果您将创建的 Handle 的值分配给您的 MessageFilter 可以访问的任何实例,例如此 class.

中的 Property
private void yourControl_HandleCreated(object sender, EventArgs e)
{
    msgFilter.OwnHandle = yourControl.Handle;
}

之后只需在 if 语句中添加第二个条件:

if (m.Msg == 0x0203 && OwnHandle == m.HWnd)
    ...