上下文菜单与TrackPopupMenu

一、上下文菜单

上下文菜单又称快捷菜单,是指出现在鼠标右键单击时弹出的菜单列表。它主要用于快速访问常用操作和提供相关信息。一般情况下,上下文菜单只包含与当前上下文相关的操作项,例如在编辑器中鼠标右键点击一个单词可以弹出以这个单词为关键字的查找菜单项。

在Windows系统中,开发者可以很方便地创建上下文菜单,并设置不同类型的菜单项,如可用性状态、快捷键等等。

下面我们来介绍一下上下文菜单的创建过程:

1.首先,我们需要在资源编辑器中添加一个菜单资源,并为它设置不同的菜单项,如下所示:

2.然后,在窗口类中的消息处理函数中添加WM_CONTEXTMENU消息处理代码,实现弹出上下文菜单的功能,如下所示:

```

case WM_CONTEXTMENU: //处理右键单击事件

{

if (hMenuContext)

{

POINT pt;

GetCursorPos(&pt);

TrackPopupMenu(hMenuContext, 0, pt.x, pt.y, 0, hWnd, NULL);

}

}

break;

```

在这里,我们使用了WindowsAPI函数TrackPopupMenu来弹出上下文菜单。它的语法如下:

```

BOOL TrackPopupMenu(

HMENU hMenu, //菜单句柄

UINT uFlags, //标志位

int x, //菜单出现位置的横坐标

int y, //菜单出现位置的纵坐标

int nReserved, //保留位

HWND hWnd, //父窗口句柄

CONST RECT *prcRect //菜单限制矩形

);

```

其中,hMenu是指定要显示的菜单句柄,uFlags是一组标志位,x和y表示菜单出现的位置,nReserved为保留位,hWnd为父窗口句柄,prcRect为菜单限制矩形。这些参数可以根据具体的需求进行设置。

3.最后,在窗口初始化的过程中,我们需要为类成员变量hMenuContext赋值:

```

hMenuContext = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_CONTEXTMENU));

hMenuContext = GetSubMenu(hMenuContext, 0);

```

其中,LoadMenu函数用于加载菜单资源,GetSubMenu函数用于获取子菜单句柄。

二、TrackPopupMenu

TrackPopupMenu函数是WindowsAPI中用于弹出菜单的函数,它可以弹出常规菜单、系统菜单和快捷菜单等等。它的语法如下:

```

BOOL TrackPopupMenu(

HMENU hMenu, //菜单句柄

UINT uFlags, //标志位

int x, //菜单出现位置的横坐标

int y, //菜单出现位置的纵坐标

int nReserved, //保留位

HWND hWnd, //父窗口句柄

CONST RECT *prcRect //菜单限制矩形

);

```

参数说明:

hMenu:要显示的菜单句柄。

uFlags:菜单标志。可以组合下面的标志:

- TPM_LEFTALIGN:菜单左对齐

- TPM_CENTERALIGN:菜单居中对齐

- TPM_RIGHTALIGN:菜单右对齐

- TPM_TOPALIGN:菜单顶部对齐

- TPM_VCENTERALIGN:菜单垂直居中对齐

- TPM_BOTTOMALIGN:菜单底部对齐

- TPM_HORIZONTAL:横向菜单

- TPM_VERTICAL:竖向菜单

- TPM_NONOTIFY:不发送WM_COMMAND消息

- TPM_RETURNCMD:返回值是菜单项的ID

- TPM_RECURSE:递归显示子菜单

- TPM_LEFTBUTTON:等同于TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTALIGN

x、y:菜单出现的位置。

hWnd:父窗口句柄。

prcRect:菜单限制矩形。

在使用TrackPopupMenu函数时,需要将菜单句柄、菜单标志、弹出的位置、父窗口句柄和菜单限制矩形等参数设置好。如果需要获取用户选择的菜单项,可以将掩码设置为TPM_RETURNCMD,并在调用函数后获取函数的返回值。

三、案例说明

下面我们来举一个使用上下文菜单和TrackPopupMenu函数的案例来说明具体实现过程。

在本例中,我们需要创建一个窗口,当用户在窗口内点击鼠标右键时,弹出上下文菜单,菜单中包含“新建”和“打开”两个选项。如果用户选择了“新建”,则在窗口中弹出一个MessageBox,显示“新建文件”;如果用户选择了“打开”,则弹出一个MessageBox,显示“打开文件”。

首先,我们需要在资源编辑器中添加一个菜单资源,并为它设置不同的菜单项,如下所示:

![image-20211202095745507](https://i.loli.net/2021/12/02/d5JocRNFOxPGTv3.png)

然后,在窗口类中的消息处理函数中添加WM_CONTEXTMENU消息处理代码,实现弹出上下文菜单的功能,如下所示:

```c++

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

static HMENU hMenu;

switch (message)

{

case WM_CREATE:

{

hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MYMENU));

hMenu = GetSubMenu(hMenu, 0);

break;

}

case WM_CONTEXTMENU:

{

if (hMenu)

{

POINT pt;

pt.x = LOWORD(lParam);

pt.y = HIWORD(lParam);

TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, hWnd, NULL);

}

break;

}

case WM_COMMAND:

{

switch (LOWORD(wParam))

{

case ID_FILE_NEW:

{

MessageBox(hWnd, L"新建文件", L"提示", MB_OK | MB_ICONINFORMATION);

break;

}

case ID_FILE_OPEN:

{

MessageBox(hWnd, L"打开文件", L"提示", MB_OK | MB_ICONINFORMATION);

break;

}

default:

break;

}

break;

}

case WM_DESTROY:

{

PostQuitMessage(0);

break;

}

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}

```

在这里,我们使用了WindowsAPI函数TrackPopupMenu来弹出上下文菜单。

在窗口初始化的过程中,我们为类成员变量hMenu赋值,同时使用LoadMenu函数和GetSubMenu函数分别加载和获取子菜单句柄。在WM_COMMAND消息中,我们使用switch语句处理用户的选择。如果选择了“新建”,则弹出一个MessageBox,显示“新建文件”;如果选择了“打开”,则弹出一个MessageBox,显示“打开文件”。

最后,我们显示该窗口并等待用户的操作:

```c++

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)

{

UNREFERENCED_PARAMETER(hPrevInstance);

UNREFERENCED_PARAMETER(lpCmdLine);

WNDCLASSW wc = {0};

wc.lpfnWndProc = WndProc;

wc.hInstance = hInstance;

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

wc.lpszClassName = L"SimpleContextMenu";

RegisterClassW(&wc);

HWND hWnd = CreateWindowW(L"SimpleContextMenu", L"SimpleContextMenu", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

MSG msg;

while (GetMessage(&msg, nullptr, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return (int)msg.wParam;

}

```

运行程序后,用户在窗口内单击鼠标右键,可以选择“新建”或“打开”,然后弹出相应的MessageBox进行提示。

上下文菜单和TrackPopupMenu函数作为WindowsAPI中比较常用的两个API之一,可以为开发者提供快速创建菜单和弹出菜单的功能,并极大地提高了程序的易用性和用户体验。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/

点赞(95) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部