Right-click on a checkbox in a CCheckListViewCtrl results in two WM_CONTEXTMENU messages...
Richard <dj_deipotent-/[email protected]> Mon, 02 Jul 2012 20:20:13 +0100
| Newsgroups | gmane.comp.windows.wtl |
|---|---|
| Message-ID | <[email protected]> |
I've noticed that a right-click on a checkbox in a CCheckListViewCtrl
results in two WM_CONTEXTMENU (also NM_RCLICK) messages being sent - one
for the mouse down (incorrect), and another for the mouse up (expected).
The point parameter indicating the cursor location, is incorrect for the
second message.
This appears to be a bug in Windows/Common Controls, as opposed to WTL,
as the MSDN docs states WM_CONTEXTMENU is generated after WM_RBUTTONUP
or WM_NCRBUTTONUP message, or when the user types SHIFT+F10 or when the
user presses and releases the VK_APPS key.
I only noticed this issue when I wrapped my call to TrackPopupMenuEx()
in a MFC style VERIFY() macro, which indicated it was failing on the
second WM_CONTEXTMENU message.
The odd thing is that when you call TrackPopupMenuEx() in the
WM_CONTEXTMENU handler function, the WM_CONTEXTMENU handler function is
called again BEFORE the WM_CONTEXTMENU handler function exits, and so
the second call to TrackPopupMenuEx() fails (no doubt due to the menu
already being displayed).
As a right-click changes the state of the checkbox, I thought about not
showing the context menu if the click occurs over the checkbox, and
initially put the following at the beginning of my handler:
UINT flags;
HitTest(point, &flags);
if (flags & LVHT_ONITEMSTATEICON)
return;
Unfortunately, when the control is in detail mode, HitTest always
returns LVHT_NOWHERE.
My current solution is to ignore the WM_CONTEXTMENU on mousedown, but
still display the context menu:
// Check this is mouse event and mouse right button is pressed or not
if ( !((point.x == -1) && (point.y == -1)) &&
(GetKeyState(VK_RBUTTON) & VKEY_DOWN))
return; // RButton pressed"));
If you don't want to display the context menu, just replace the above with:
static bool bRightClickOnCheckbox = false;
if (bRightClickOnCheckbox) {
bRightClickOnCheckbox = false;
return;
}
// Check this is mouse event and mouse right button is pressed or not
if ( !((point.x == -1) && (point.y == -1)) &&
(GetKeyState(VK_RBUTTON) & VKEY_DOWN)) {
bRightClickOnCheckbox = true;
return; // RButton pressed"));
}
Something like this could be added to
CCheckListViewCtrl::OnContextMenu(), as a workaround to the bug, with
the bRightClickOnCheckbox as a template parameter, to control whether
the menu is displayed.
Best Regards,
Richard B.
------------------------------------
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/wtl/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/wtl/join
(Yahoo! ID required)
<*> To change settings via email:
[email protected]
[email protected]
<*> To unsubscribe from this group, send an email to:
[email protected]
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/