我创建了一个通知图标:
notifyIcon.cbSize = sizeof(NOTIFYICONDATA);
notifyIcon.hWnd = mainWnd;
notifyIcon.uID = 100;
notifyIcon.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
notifyIcon.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LOGO));
notifyIcon.dwState = NIS_SHAREDICON;
notifyIcon.uVersion = NOTIFYICON_VERSION;
notifyIcon.uTimeout = 15000;
notifyIcon.uCallbackMessage = APP_MSG_TRAY;
wcscpy_s(notifyIcon.szTip, 127, WTXT_APP_TRAY_TOOLTIP);
Shell_NotifyIcon(NIM_ADD, ¬ifyIcon);
Shell_NotifyIcon(NIM_SETVERSION, ¬ifyIcon);
在WM_RBUTTONDOWN和WM_CONTEXTMENU上有一个上下文菜单弹出窗口,如下所示:
MENUITEMINFO separatorBtn = {0};
separatorBtn.cbSize = sizeof(MENUITEMINFO);
separatorBtn.fMask = MIIM_FTYPE;
separatorBtn.fType = MFT_SEPARATOR;
HMENU hMenu = CreatePopupMenu();
if(hMenu) {
InsertMenu(hMenu, -1, MF_BYPOSITION, APP_OPEN_OPTIONS, WTXT_OPTIONS);
InsertMenuItem(hMenu, -1, FALSE, &separatorBtn);
InsertMenu(hMenu, -1, MF_BYPOSITION, APP_MSG_EXIT, WTXT_EXIT);
POINT pt;
GetCursorPos(&pt);
SetForegroundWindow(mainWnd);
TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, mainWnd, NULL);
PostMessage(mainWnd, WM_NULL, 0, 0);
DestroyMenu(hMenu);
}
它工作正常,但上下文菜单并不总是消失。有时(经常)如果你有ie。系统托盘中的winamp和我的应用程序图标,如果您右键单击我的应用程序和winamp,将显示机器人菜单,并且在您单击某个项目之前我的菜单不会自动消失。
有什么想法吗?
感谢...
答案 0 :(得分:8)
要显示通知图标的上下文菜单,当前窗口必须是应用程序调用TrackPopupMenu或TrackPopupMenuEx之前的前台窗口。否则,当用户点击菜单外部或创建菜单的窗口(如果可见)时,菜单不会消失。
SetForegroundWindow(hDlg);
TrackPopupMenu( hSubMenu,
TPM_RIGHTBUTTON,
pt.x,
pt.y,
0,
hDlg,
NULL);
答案 1 :(得分:3)
不要捕获WM_RBUTTONDOWN而是捕获WM_RBUTTONUP。当然不要同时处理WM_RBUTTONUP和WM_CONTEXTMENU,因为它们将两者得到处理,并且每次右键单击都会显示两次上下文菜单。 两次显示菜单会产生你描述的效果:菜单显示,但似乎没有消失(因为它会立即再次显示)。
答案 2 :(得分:1)
有些应用试图破解通知区域(托盘)API的限制。他们将挂钩资源管理器窗口并侦听Windows消息。这让他们可以做其他事情不可能的事情,但它不可避免地会破坏其他应用程序的稳定性。获得两个上下文菜单是这种麻烦的明确标志。
你有一个很好的领导,可以做什么样的程序,它有一个图标。一个接一个地杀死他们,直到你找到邪恶的行为者。除了没有运行它或向供应商抱怨之外,你可能做的不多。
答案 3 :(得分:0)
你似乎已经有两个记录的错误修正(SetForegroundWindow& WM_NULL)我会说除此之外的任何东西都是windows中的错误。
如果你真的想做hacky事情,你可能会得到WM_INITMENU *中的菜单窗口句柄(我不是指HMENU,而是菜单的HWND)并隐藏该窗口。