简体   繁体   中英

C# Disable click/doubleClick or any WindowsMessage

My goal is to disable all DoubleClick() events in my application. Just simply unsubscribing from those events is not possbile, because those are external custom controls. So I am aiming for disabling either the DoubleClick() for those controls or my whole application, it doesn't really matter.

What I am trying to do is to intervene once the window gets a WindowsMessage WM and the ID number Message.Msg is the code of eg a Button.Click() event.

private const int WM_COMMAND = // ???

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

But no matter which WindowsMessage notification code I use, I don't get the correct one which gets fired once a control gets clicked. But I was abel to intervene on a DoubeClick() on the 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);
}

This works totally fine and disabels a DoubleClick on the client area and non client area of the Form . But in which area do I locate when I am hovering a control? Because those WindowsMessages referred to either the client area and non client area dont' get fired when I am on a control.


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

The WM_COMMAND message has this notfication code:

private const int WM_COMMAND = 0x0111;

So when I try to react to this message being sent I can't, because this message doesn't get fired.

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

    base.WndProc(ref m);
}

What do I miss or missunderstand about this WindowsMessage?

Since no one posted an answer yet and I found a well working solution here is my attempt to disable all DoubleClick() s or just for one/a few desired Control /s.

The problem is that WndProc() doesn't filter or respond to all WM s that are being sent. Therefore the WM for a default doubleClick on the non client area 0x0203 can't get detected. So I went deeper to already filter the WM s before they reach WndProc() . One way is to use a MessageFilter that is being assigned to my Application .

private MessageFilter msgFilter = new MessageFilter();

Application.AddMessageFilter(msgFilter);

The method Param is an object of my own class MessageFilter , which needs to implement the IMessageFilter Interface in order to use it's PreFilterMessage() . This method gets invoked for each single WM that gets send to your application.

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

So basically once there is a WM with the desired Message.Msg ID, I set the Result to zero so the DoubleClick() is completely disabled for the whole application.


Later on it turned out it would be better to disable the DoubleClick() only from one Control . Since every Control in Windows has a unique Handle HWnd , which is part of the Message , I can use it to scan if the certain Message aims to my specific single Control .

When you create your Control either subscribe in the .Designer.cs to the event:

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

Or if it's a custom Control subscribe to the event after it's creation. In the event you assign the value of the created Handle to any instance your MessageFilter has access to, like a Property in this class.

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

After that simply add a second condition to the if statement:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM