I create my system tray icon using Shell_NotifyIcon
and then trap its WM_LBUTTONDBLCLK
notifications for when a user double-clicks the icon (I use it show a dialog window.) I also trap WM_RBUTTONDOWN
notifications to show the context menu.
Now I'm thinking that it would be nice to show a context menu after a single left click. But how do I do that?
If I trap WM_LBUTTONDOWN
and show my context menu it works fine. But then when someone double-clicks the icon, it first shows my context menu and then displays the dialog window. So I'm not sure how to overcome this?
EDIT: Here's my code:
NOTIFYICONDATA nid;
memset(&nid, 0, sizeof(nid));
nid.cbSize = sizeof(nid);
nid.hWnd = this->GetSafeHwnd();
nid.uID = TRAY_ICON_ID1;
nid.uFlags = NIF_ICON;
nid.uCallbackMessage = TRAY_NOTIFICATION_ID1;
nid.hIcon = ghIcon;
Shell_NotifyIcon(NIM_ADD, &nid);
and then:
ON_MESSAGE(TRAY_NOTIFICATION_ID1, OnTrayIconNotifications)
LRESULT OnTrayIconNotifications(WPARAM wParam, LPARAM lParam)
{
UINT uID = (UINT)wParam;
UINT uMouseMsg = (UINT)lParam;
if(uID == TRAY_ICON_ID1)
{
switch(uMouseMsg)
{
case WM_RBUTTONDOWN:
{
//Show context menu
//...
int nChosenCmd = TrackPopupMenu(hMenu,
TPM_RIGHTALIGN | TPM_TOPALIGN |
TPM_LEFTBUTTON | TPM_VERPOSANIMATION |
TPM_HORNEGANIMATION | TPM_RETURNCMD,
x, y, 0,
this->GetSafeHwnd(), NULL);
}
break;
case WM_LBUTTONDBLCLK:
{
//Show dialog window
CDialogBasedClass dlg(this);
dlg.DoModal();
}
break;
}
}
return 0;
}
I suspect you will have to get smart about it.
In your
WM_LBUTTONDOWN
click handler, set a timer that expires after the system's double click time has elapsed. In yourWM_LBUTTONDBLCLICK
handler check if that timer is active and if it is, cancel it.If the timer expires that means the user clicked your icon but did not go ahead and double-click it; that means it's time to show the context menu.
Show context menu on
WM_RBUTTONDOWN
orWM_CONTEXTMENU
. Regarding left button single and double click, correct design requires double-click handler as continuation of single click. For example, in Windows Explorer single click selects a file, and double click opens it. Single click handler always works before double click handler, and this should look natural. In your case I would show a menu on right click, and dialog on left click.Solutions based on timers and delays create buggy and unreliable code.