diff --git a/base/shell/explorer/syspager.cpp b/base/shell/explorer/syspager.cpp index 5340ba49212..1755ebedde3 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;