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 e.g. 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)
...