UPDATED
The thing happens in void WndProc(ref Message m)
. I tried to reproduce the problem with different control (PictureBox
). Left double click gave:
protected virtual void WndProc(ref Message m)
{
// ...
switch (m.Msg)
{
// ...
case 514:
WmMouseUp(ref m, MouseButtons.Left, 1);
return;
// ...
}
// ...
}
And right double click resulted into call to:
protected virtual void WndProc(ref Message m)
{
// ...
switch (m.Msg)
{
// ...
case 517:
WmMouseUp(ref m, MouseButtons.Right, 1);
return;
// ...
}
// ...
}
Where void WmMouseUp(ref Message m, MouseButtons button, int clicks)
looks like:
private void WmMouseUp(ref Message m, MouseButtons button, int clicks)
{
// ...
OnDoubleClick(new MouseEventArgs(button, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
OnMouseDoubleClick(new MouseEventArgs(button, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
// ...
}
Both OnDoubleClick
and OnMouseDoubleClick
fire with MouseEventArgs
. That's why this solution works.
private void control_DoubleClick(object sender, EventArgs e)
{
if ((e as MouseEventArgs)?.Button == MouseButtons.Right)
return;
// do your stuff
}
But situation is different with ListView
:
protected virtual void WndProc(ref Message m)
{
// ...
switch (m.Msg)
{
// ...
case 514:
case 517: // m.Msg value
case 520:
{
NativeMethods.LVHITTESTINFO lvhi = new NativeMethods.LVHITTESTINFO();
int indexOfClickedItem = GetIndexOfClickedItem(lvhi);
if (!base.ValidationCancelled && listViewState[262144] && indexOfClickedItem != -1)
{
listViewState[262144] = false;
OnDoubleClick(EventArgs.Empty);
OnMouseDoubleClick(new MouseEventArgs(downButton, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
}
if (!listViewState[524288])
{
OnMouseUp(new MouseEventArgs(downButton, 1, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
listViewState[1048576] = false;
}
ItemCollectionChangedInMouseDown = false;
listViewState[524288] = true;
base.CaptureInternal = false;
return;
}
// ...
}
// ...
}
It fires OnDoubleClick
with EventArgs.Empty
. So first solution doesn't work.
Workaround could be using a patched ListView
:
public class PatchedListView : ListView
{
protected override void WndProc(ref Message m)
{
var suppress = m.Msg == 517 &&
Enum.TryParse(typeof(ListView).GetField("downButton", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this).ToString(),
out MouseButtons mouseButtons) &&
mouseButtons == MouseButtons.Right;
if (suppress)
return;
base.WndProc(ref m);
}
}