win32 创建右键菜单

一般来说,创建并使用快捷菜单,可以按照以下步骤进行:
1、用资源编辑器创建菜单。
2、当我们在窗口上按下鼠标右键,当系统处理WM_RBUTTONUP时会向我们的应用程序发送一条WM_CONTEXTMENU消息,我们通过响应这条消息来决定是否弹出菜单。
3、计算菜单弹出的位置,一般在我们鼠标指针的右下方,该坐标是基于屏幕的,不是窗口的。
4、调用TrackPopupMenu函数显示快捷菜单。
5、因为这种菜单是不属于某个窗口的,它的内存资源不会在窗口销毁时被回收,因此,在TrackPopupMenu返回后要调用DestroyMenu来销毁菜单的资源,释放内存。
创建菜单资源-并设置ID
win32 创建右键菜单
文章图片

接下来就是捕捉WM_CONTEXTMENU消息。显示菜单。

case WM_CONTEXTMENU: { RECT rect; POINT pt; // 获取鼠标右击是的坐标 pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); //获取客户区域大小 GetClientRect((HWND)wParam, &rect); //把屏幕坐标转为客户区坐标 ScreenToClient((HWND)wParam, &pt); //判断点是否位于客户区域内 if (PtInRect(&rect, pt)) { //加载菜单资源 HMENU hroot = LoadMenu((HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDR_CONTEXT)); if (hroot) { // 获取第一个弹出菜单 HMENU hpop = GetSubMenu(hroot, 0); // 把客户区坐标还原为屏幕坐标 ClientToScreen((HWND)wParam, &pt); //显示快捷菜单 TrackPopupMenu(hpop, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, (HWND)wParam, NULL); // 用完后要销毁菜单资源 DestroyMenu(hroot); } } }

点击做出反应效果
case 32781: MessageBox(hWnd, L"哈哈。", L"提示", MB_OK); break; case 32782: MessageBox(hWnd, L"呵呵。", L"提示", MB_OK); break; case 32783: MessageBox(hWnd, L"嘎嘎。", L"提示", MB_OK); break; }

定义
#define ID_haha32781 #define ID_hehe32782 #define ID_gaga32783

根据MSDN文档的说明,WM_CONTEXTMENU消息的wParam参数指的是弹出菜单的窗口的句柄,lParam参数的低字位是鼠标指针的水平坐标,高字位指的是垂直坐标。
但我们不用自己去转换,我们通过GET_X_LPARAM和GET_Y_LPARAM两个宏可以把lParam中的值转为坐标值,类型为int,要使用这两个宏,需要包含WindowsX.h头文件。接着调用TrackPopupMenu来显示菜单,最后销毁菜单。
现在在窗口的标题栏上右击,快捷菜单不会再出现了,但是,同时,系统菜单也没有出现。因为系统菜单是由系统来处理的,所以,解决这问题很简单,只要我们把WM_CONTEXT消息发回给系统来处理就行了。
方法一:我们判断了如果右击点在窗口的客户区域时显示菜单,那么,如果不在这个区域内,就把消息再传回给系统处理。
else { return DefWindowProc(hWnd, message, wParam, lParam); }

【win32 创建右键菜单】方法二:在WindowsProc函数的最后,统一把所有消息都返回给操作系统处理。
default: return DefWindowProc(hWnd, message, wParam, lParam); } return DefWindowProc(hWnd, message, wParam, lParam);

    推荐阅读