https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4127024b0d7ef28e041fa6...
commit 4127024b0d7ef28e041fa61896b3eadcafd2fe36 Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Mon Apr 2 21:06:09 2018 +0200 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@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;