https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4127024b0d7ef28e041fa…
commit 4127024b0d7ef28e041fa61896b3eadcafd2fe36
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Apr 2 21:06:09 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Mon Apr 2 21:13:35 2018 +0200
[EXPLORER] Handle WM_CONTEXTMENU message in CNotifyToolbar and BN_CLICKED notification
in CSysPagerWnd.
With these, we generate the WM_CONTEXTMENU and NIN_(KEY)SELECT
shell icon notifications that applications expect when they handle
shell notification icons with uVersion >= 3.
This fixes in particular the previously unresponsive icon of KVIrc 4.x,
and more generally *all* the notifiation icons of Qt applications.
CORE-10605 #resolve
---
base/shell/explorer/syspager.cpp | 110 +++++++++++++++++++++++++++++++++++++--
1 file changed, 105 insertions(+), 5 deletions(-)
diff --git a/base/shell/explorer/syspager.cpp b/base/shell/explorer/syspager.cpp
index 5340ba4921..1755ebedde 100644
--- a/base/shell/explorer/syspager.cpp
+++ b/base/shell/explorer/syspager.cpp
@@ -165,12 +165,14 @@ public:
bool SendNotifyCallback(InternalIconData* notifyItem, UINT uMsg);
private:
+ LRESULT OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
VOID SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN WPARAM wParam);
LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnTooltipShow(INT uCode, LPNMHDR hdr, BOOL& bHandled);
public:
BEGIN_MSG_MAP(CNotifyToolbar)
+ MESSAGE_HANDLER(WM_CONTEXTMENU, OnCtxMenu)
MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseEvent)
NOTIFY_CODE_HANDLER(TTN_SHOW, OnTooltipShow)
END_MSG_MAP()
@@ -201,6 +203,7 @@ public:
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnGetInfoTip(INT uCode, LPNMHDR hdr, BOOL& bHandled);
LRESULT OnCustomDraw(INT uCode, LPNMHDR hdr, BOOL& bHandled);
+ LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnBalloonPop(UINT uCode, LPNMHDR hdr, BOOL& bHandled);
@@ -240,6 +243,7 @@ public:
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
+ MESSAGE_HANDLER(WM_COMMAND, OnCommand)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_CONTEXTMENU, OnCtxMenu)
MESSAGE_HANDLER(WM_TIMER, OnTimer)
@@ -1015,6 +1019,54 @@ VOID CNotifyToolbar::ResizeImagelist()
SetButtonSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
}
+LRESULT CNotifyToolbar::OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
+{
+ bHandled = FALSE;
+
+ /*
+ * WM_CONTEXTMENU message can be generated either by the mouse,
+ * in which case lParam encodes the mouse coordinates where the
+ * user right-clicked the mouse, or can be generated by (Shift-)F10
+ * keyboard press, in which case lParam equals -1.
+ */
+ INT iBtn = GetHotItem();
+ if (iBtn < 0)
+ return 0;
+
+ InternalIconData* notifyItem = GetItemData(iBtn);
+
+ if (!::IsWindow(notifyItem->hWnd))
+ return 0;
+
+ if (notifyItem->uVersionCopy >= NOTIFYICON_VERSION)
+ {
+ /* Transmit the WM_CONTEXTMENU message if the notification icon supports it */
+ ::SendNotifyMessage(notifyItem->hWnd,
+ notifyItem->uCallbackMessage,
+ notifyItem->uID,
+ WM_CONTEXTMENU);
+ }
+ else if (lParam == -1)
+ {
+ /*
+ * Otherwise, and only if the WM_CONTEXTMENU message was generated
+ * from the keyboard, simulate right-click mouse messages. This is
+ * not needed if the message came from the mouse because in this
+ * case the right-click mouse messages were already sent together.
+ */
+ ::SendNotifyMessage(notifyItem->hWnd,
+ notifyItem->uCallbackMessage,
+ notifyItem->uID,
+ WM_RBUTTONDOWN);
+ ::SendNotifyMessage(notifyItem->hWnd,
+ notifyItem->uCallbackMessage,
+ notifyItem->uID,
+ WM_RBUTTONUP);
+ }
+
+ return 0;
+}
+
bool CNotifyToolbar::SendNotifyCallback(InternalIconData* notifyItem, UINT uMsg)
{
if (!::IsWindow(notifyItem->hWnd))
@@ -1045,10 +1097,10 @@ bool CNotifyToolbar::SendNotifyCallback(InternalIconData*
notifyItem, UINT uMsg)
}
else
{
- SendMessage(notifyItem->hWnd,
- notifyItem->uCallbackMessage,
- notifyItem->uID,
- uMsg);
+ ::SendMessage(notifyItem->hWnd,
+ notifyItem->uCallbackMessage,
+ notifyItem->uID,
+ uMsg);
}
return false;
}
@@ -1087,7 +1139,6 @@ VOID CNotifyToolbar::SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN
WPARAM wPar
LRESULT CNotifyToolbar::OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
-
INT iBtn = HitTest(&pt);
if (iBtn >= 0)
@@ -1376,6 +1427,55 @@ LRESULT CSysPagerWnd::OnCustomDraw(INT uCode, LPNMHDR hdr,
BOOL& bHandled)
return TRUE;
}
+LRESULT CSysPagerWnd::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
+{
+ bHandled = FALSE;
+
+ /* Handles the BN_CLICKED notifications sent by the CNotifyToolbar member */
+ if (HIWORD(wParam) != BN_CLICKED)
+ return 0;
+
+ INT iBtn = LOWORD(wParam);
+ if (iBtn < 0)
+ return 0;
+
+ InternalIconData* notifyItem = Toolbar.GetItemData(iBtn);
+
+ if (!::IsWindow(notifyItem->hWnd))
+ return 0;
+
+ // TODO: Improve keyboard handling by looking whether one presses
+ // on ENTER, etc..., which roughly translates into "double-clicking".
+
+ if (notifyItem->uVersionCopy >= NOTIFYICON_VERSION)
+ {
+ /* Use new-style notifications if the notification icon supports them */
+ ::SendNotifyMessage(notifyItem->hWnd,
+ notifyItem->uCallbackMessage,
+ notifyItem->uID,
+ NIN_SELECT); // TODO: Distinguish with NIN_KEYSELECT
+ }
+ else if (lParam == -1)
+ {
+ /*
+ * Otherwise, and only if the icon was selected via the keyboard,
+ * simulate right-click mouse messages. This is not needed if the
+ * selection was done by mouse because in this case the mouse
+ * messages were already sent.
+ */
+ ::SendNotifyMessage(notifyItem->hWnd,
+ notifyItem->uCallbackMessage,
+ notifyItem->uID,
+ WM_LBUTTONDOWN); // TODO: Distinguish with double-click
WM_LBUTTONDBLCLK
+ ::SendNotifyMessage(notifyItem->hWnd,
+ notifyItem->uCallbackMessage,
+ notifyItem->uID,
+ WM_LBUTTONUP);
+ }
+
+ return 0;
+}
+
LRESULT CSysPagerWnd::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
LRESULT Ret = TRUE;