参考博客:创建右键菜单
今天的任务是创建右键菜单,右键菜单即单击鼠标右键弹出的菜单,比如在markdown编辑器右键弹出的带剪切、复制、粘贴等菜单项的菜单。这个菜单称为快捷菜单,快捷菜单没有顶层菜单,使用TrackPopup
函数创建。
下面是这个函数的说明:注意x,y为屏幕坐标
BOOL TrackPopupMenu(
HMENU hMenu,
UINT uFlags,
int x,
int y,
int nReserved,
HWND hWnd,
CONST RECT *prcRect
);
/**
1、hMenu
Type: HMENU
A handle to the shortcut menu to be displayed. The handle can be obtained by calling CreatePopupMenu to create a new shortcut menu, or by calling GetSubMenu to retrieve a handle to a submenu associated with an existing menu item.
2、uFlags
Type: UINT
Use zero of more of these flags to specify function options.
3、x
Type: int
The horizontal location of the shortcut menu, in screen coordinates.
4、y
Type: int
The vertical location of the shortcut menu, in screen coordinates.
5、nReserved
Type: int
Reserved; must be zero.
6、hWnd
Type: HWND
A handle to the window that owns the shortcut menu. This window receives all messages from the menu. The window does not receive a WM_COMMAND message from the menu until the function returns. If you specify TPM_NONOTIFY in the uFlags parameter, the function does not send messages to the window identified by hWnd. However, you must still pass a window handle in hWnd. It can be any window handle from your application.
7、prcRect
Type: const RECT*
Ignored.
**/
1、步骤
创建资源文件
首先我们要创建一个资源文件,创建一个菜单资源,这里的底层菜单内容可以随便设置,因为在快捷菜单中看不见。
处理右键点击事件系统发送给应用的消息WM_RBUTTONUP
设置菜单弹出的位置,设置为右键点击时的屏幕坐标
显示快捷菜单,利用
TrackPopupMenu
函数销毁菜单资源
2、代码
这段代码写在WindowProc函数中,用于消息响应
case WM_RBUTTONUP:
{
HMENU hroot = LoadMenu((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDR_MENU2));
if (hroot) {
HMENU hpop = GetSubMenu(hroot, 0);
POINT pt;
//lParam低位储存x客户区坐标,高位储存y客户区坐标
//注意这里不能用LOWORD()和HIWORD()!
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
//由于是x,y是客户区坐标不是屏幕坐标,因此需要转换
ClientToScreen(hwnd, &pt);
TrackPopupMenu(hpop, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTALIGN, pt.x, pt.y, 0, hwnd, NULL);
//销毁资源,释放内存
DestroyMenu(hroot);
}
break;
}
3、运行结果
参考博客中还提到了系统菜单的消息被屏蔽,但是我这里没有出现这种情况:
这是由于参考博客中用的消息是WM_CONTEXTMENU,而我这里用的是WM_RBUTTONUP,前者的x,y是基于屏幕的坐标,需要判断点击的位置是否在客户区内,而WM_RBUTTONUP的x,y就是客户区坐标。WM_CONTEXTMENU除了在点击右键时会发送外,按下shift+f10也会发送。