C#禁用click / doubleClick或任何WindowsMessage

时间:2018-01-15 14:41:35

标签: c# windows-messages

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

我尝试做的是在窗口获得WindowsMessage WM后进行干预,并且ID号Message.Msg是例如Button.Click()事件。

private const int WM_COMMAND = // ???

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

但无论我使用哪种WindowsMessage通知代码,我都没有得到一个在点击控件后被触发的正确代码。但是我在DoubeClick()Form进行了干预。

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

这完全正常,并且在DoubleClick客户区非客户区上消除了Form。但是当我悬停控件时,我在哪个区域中找到了?因为当我在控件上时,那些引用客户区非客户区的WindowsMessages不会被触发。

  

用户点击按钮时发送。   按钮的父窗口通过WM_COMMAND消息接收此通知代码。

MSDN doc about a button click notifaction message

WM_COMMAND消息包含此notfication代码:

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有什么想念或误解?

1 个答案:

答案 0 :(得分:0)

由于还没有人发布答案,我在这里找到了一个运行良好的解决方案,我尝试禁用所有DoubleClick()或仅限一个/几个所需的Control / s。

问题是WndProc()不会过滤或回复正在发送的所有 WM。因此,无法检测到非客户区 WM上的默认doubleClick 0x0203。所以我更深入地在WM到达WndProc()之前对其进行了过滤。一种方法是使用分配给MessageFilter的{​​{1}}。

Application

方法Param是我自己的类private MessageFilter msgFilter = new MessageFilter(); Application.AddMessageFilter(msgFilter); 的对象,它需要实现MessageFilter接口才能使用它IMessageFilter。调用每个单个PreFilterMessage()的方法,并将其发送到您的应用程序。

WM

因此,基本上只有class MessageFilter : IMessageFilter { public bool PreFilterMessage(ref Message m) { if (m.Msg == 0x0203) { m.Result = IntPtr.Zero; return true; } else return false; } } 具有所需的WM ID,我就会将Message.Msg设置为Result,以便完全禁用zero整个申请。

后来发现最好只从一个DoubleClick()禁用DoubleClick()。由于Windows中的每个Control都有一个唯一的Control,它是Handle HWnd的一部分,我可以用它来扫描某个Message是否针对我的特定单Message 1}}。

当您创建Control时,您可以在Control订阅该活动:

.Designer.cs

或者,如果它是自定义this.yourControl.HandleCreated += new System.EventHandler(this.yourControl_HandleCreated); ,则在创建后订阅该事件。如果您将已创建的Control的值分配给Handle有权访问的任何实例,例如此类中的MessageFilter

Property

之后,只需在private void yourControl_HandleCreated(object sender, EventArgs e) { msgFilter.OwnHandle = yourControl.Handle; } 语句中添加第二个条件:

if