c – 通知图标接收WM_LBUTTONDBLCLK但不接收WM_CONTEXTMENU
我在基于对话框的应用程序中添加了一个通知图标,当双击该图标时它收到了WM_LBUTTONDBLCLK,但是当右键单击图标或者用键盘突出显示图标并且上下文菜单键是上传时,它没有收到WM_CONTEXTMENU按下.我根据
Windows 7.1 SDK示例中的示例使用了通知图标.所以,我不知道我哪里出错了,或者为什么这不起作用.
注意:如果我将WM_CONTEXTMENU更改为WM_RBUTTONUP,它会收到事件,但光标坐标是错误的. /******************************************************************************/ /* Menu Resource */ /******************************************************************************/ LANGUAGE LANG_NEUTRAL,SUBLANG_NEUTRAL IDR_TRAYMENU MENU { POPUP "" { MENUITEM "&Show Status Window",IDM__SHOW_STATUS_WINDOW MENUITEM "&About",IDM__ABOUT MENUITEM SEPARATOR MENUITEM "&Exit",IDM__EXIT } } /******************************************************************************/ /* WinMain() */ /******************************************************************************/ int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow ) { // ... code unrelated to icon // Enable Visual Styles InitCommonControls(); // create the main dialog if( NULL == (hWnd=CreateDialog(hInstance,MAKEINTRESOURCE(IDD_MAINDLG),NULL,(DLGPROC)WndProc)) ) { MessageBox( NULL,"Error creating the main dialog!",MB_OK | MB_ICONERROR ); return -1; } // ... code unrelated to icon MSG msg; while( GetMessage(&msg,0) && IsWindow(hWnd) ) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } /******************************************************************************/ /* WndProc() */ /******************************************************************************/ BOOL CALLBACK WndProc(HWND hWndDlg,UINT Message,WPARAM wParam,LPARAM lParam) { switch(Message) { case WM_INITDIALOG: { // ... code unrelated to icon hIcon = (HICON)LoadImage( GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_DDCMP),IMAGE_ICON,16,LR_DEFAULTSIZE ); // Setup the system tray icon memset( &nid,sizeof(NOTIFYICONDATA) ); nid.cbSize = sizeof(NOTIFYICONDATA); nid.hWnd = hWndDlg; nid.uID = 0xDDC; nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_SHOWTIP; nid.uCallbackMessage = WM_APP + 0xDDC; nid.hIcon = hIcon; strcpy( nid.szTip,"DDCMP Driver" ); Shell_NotifyIcon( NIM_ADD,&nid ); // ... code unrelated to icon return true; } break; case WM_APP + 0xDDC: { switch( LOWORD(lParam) ) { case WM_CONTEXTMENU: { MessageBox( hWndDlg,"This message box never shows up.",MB_OK | MB_SYSTEMMODAL ); HMENU hMenu = LoadMenu(GetModuleHandle(NULL),MAKEINTRESOURCE(IDR_TRAYMENU)); if( hMenu ) { HMENU hSubMenu = GetSubMenu(hMenu,0); if( hSubMenu ) { SetForegroundWindow( hWndDlg ); POINT pt = { LOWORD(wParam),HIWORD(wParam) }; UINT uFlags = TPM_RIGHTBUTTON; if( 0 != GetSystemMetrics(SM_MENUDROPALIGNMENT) ) uFlags |= TPM_RIGHTALIGN; else uFlags |= TPM_LEFTALIGN; TrackPopupMenuEx( hSubMenu,uFlags,pt.x,pt.y,hWndDlg,NULL ); } DestroyMenu( hMenu ); } } break; case WM_LBUTTONDBLCLK: if( IsWindowVisible(hWndDlg) ) ShowWindow( hWnd,SW_HIDE ); else ShowWindow( hWnd,SW_SHOW ); break; } return true; } break; case WM_CLOSE: ShowWindow( hWndDlg,SW_HIDE ); break; case WM_DESTROY: case WM_QUIT: { Shell_NotifyIcon( NIM_DELETE,&nid ); // ... code unrelated to icon return true; } break; } return false; } 这是Windows 7.1 SDK示例中的WndProc LRESULT CALLBACK WndProc(HWND hwnd,UINT message,LPARAM lParam) { static HWND s_hwndFlyout = NULL; static BOOL s_fCanShowFlyout = TRUE; switch (message) { case WM_CREATE: // add the notification icon if (!AddNotificationIcon(hwnd)) { MessageBox(hwnd,L"Please read the ReadMe.txt file for troubleshooting",L"Error adding icon",MB_OK); return -1; } break; case WM_COMMAND: { int const wmId = LOWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_LOWINK: ShowLowInkBalloon(); break; case IDM_NOINK: ShowNoInkBalloon(); break; case IDM_PRINTJOB: ShowPrintJobBalloon(); break; case IDM_OPTIONS: // placeholder for an options dialog MessageBox(hwnd,L"Display the options dialog here.",L"Options",MB_OK); break; case IDM_EXIT: DestroyWindow(hwnd); break; case IDM_FLYOUT: s_hwndFlyout = ShowFlyout(hwnd); break; default: return DefWindowProc(hwnd,message,wParam,lParam); } } break; case WMAPP_NOTIFYCALLBACK: switch (LOWORD(lParam)) { case NIN_SELECT: // for NOTIFYICON_VERSION_4 clients,NIN_SELECT is prerable to listening to mouse clicks and key presses // directly. if (IsWindowVisible(s_hwndFlyout)) { HideFlyout(hwnd,s_hwndFlyout); s_hwndFlyout = NULL; s_fCanShowFlyout = FALSE; } else if (s_fCanShowFlyout) { s_hwndFlyout = ShowFlyout(hwnd); } break; case NIN_BALLOONTIMEOUT: RestoreTooltip(); break; case NIN_BALLOONUSERCLICK: RestoreTooltip(); // placeholder for the user clicking on the balloon. MessageBox(hwnd,L"The user clicked on the balloon.",L"User click",MB_OK); break; // // // As you can very plainly see,the Windows SDK Sample ONLY used WM_CONTEXTMNEU // // case WM_CONTEXTMENU: { POINT const pt = { LOWORD(wParam),HIWORD(wParam) }; ShowContextMenu(hwnd,pt); } break; } break; case WMAPP_HIDEFLYOUT: HideFlyout(hwnd,s_hwndFlyout); s_hwndFlyout = NULL; s_fCanShowFlyout = FALSE; break; case WM_TIMER: if (wParam == HIDEFLYOUT_TIMER_ID) { // please see the comment in HideFlyout() for an explanation of this code. KillTimer(hwnd,HIDEFLYOUT_TIMER_ID); s_fCanShowFlyout = TRUE; } break; case WM_DESTROY: DeleteNotificationIcon(); PostQuitMessage(0); break; default: return DefWindowProc(hwnd,lParam); } return 0; } 解决方法
通知图标多年来改变了行为.出于与预先存在的代码兼容的原因,您必须选择加入新行为.如果您不选择加入,则不会收到WM_CONTEXTMENU消息.相反,你必须回应WM_RBUTTONUP.即使您从键盘调用上下文菜单,系统仍会发送WM_RBUTTONUP.您必须通过调用GetCursorPos获取光标位置,以便知道显示菜单的位置.
您可以通过在NIM_ADD调用后调用Shell_NotifyIcon传递NIM_SETVERSION,按照documentation中的描述选择新行为(和WM_CONTEXTMENU).据推测,您正在查看的SDK示例是在某处做的.我的猜测是你的代码遗漏了什么. 文档的关键摘录在备注部分:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |