[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
This commit is contained in:
Hermès Bélusca-Maïto 2018-04-02 21:06:09 +02:00
parent bb819f1528
commit 4127024b0d
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -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;