程序地带

C++ 重载EditBox默认ContextMenu



C++ 重载EditBox默认ContextMenu
问题背景自定义右键菜单重载系统默认右键菜单参考资料重要说明


问题背景

      在做windows下的C++客户端程序开发的时候,经常会遇到自定义右键菜单的功能点的开发。       这时候,我们一般只需要在窗口的事件过程中处理WM_CONTEXTMENU消息。处理时,根据需要可以使用CreatePopupMenu创建弹出菜单,并插入指定的子菜单项,最后处理对应菜单项的消息这样的流程来实现一个自定义的右键菜单列表。也可以通过拿到菜单项的句柄,枚举并修改菜单列表的形式重载一些已经实现的或者已经定义的菜单列表。       之前遇到一个需求,需要继承Edit默认的右键菜单,在此基础上添加一些自定义的右键菜单项。然而,按照之前的理解,写代码的过程中发现,WM_CONTEXTMENU消息触发的时候,不能获取到默认的右键菜单句柄信息,也就拿不到右键菜单中的菜单列表条目。因此也不能继续进行右键菜单项的自定义操作。下面用代码演示一下,一般自定义右键菜单的方法和在editbox中实现重载默认Context的方法。


自定义右键菜单

在这里用代码表示一般的右键菜单创建和处理的过程:


//编辑框事件处理
#define EDIT_NEW_MENU_ITEM WM_USER + 800
static LRESULT CALLBACK WndProcForEditCtrl(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_CONTEXTMENU: {
//创建菜单项列表
HMENU popup = CreatePopupMenu();
WCHAR temp[50] = {0};
wcscpy(temp, L"自定义菜单");
AppendMenu(popup, MF_STRING, (UINT_PTR)EDIT_NEW_MENU_ITEM, tmp);
POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
TrackPopupMenu(popup, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, pt.x,
pt.y, 0,hwnd, nullptr);
return true;
}
break;
case EDIT_NEW_MENU_ITEM:{
//根据具体的需求处理消息
}
break;
default:
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
重载系统默认右键菜单
//获取列表中pos处的菜单项
MENUITEMINFO GetMenuInfoByPosition(HMENU menu, UINT nPos) {
TCHAR szMenuStr[256] = {0};
MENUITEMINFO mInfo = {0};
mInfo.cbSize = sizeof(mInfo);
mInfo.fMask = 0 |MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU| MIIM_TYPE| 0;
mInfo.dwTypeData = szMenuStr;
mInfo.cch = _countof(szMenuStr);
GetMenuItemInfo(menu, nPos, TRUE, &mInfo);
return mInfo;
}
#define EDIT_NEW_MENU_ITEM WM_USER + 800
static bool isInitMenu = true;
static LRESULT CALLBACK WndProcForEditCtrl(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_CONTEXTMENU: {
isInitMenu = true;
} break;
case WM_ENTERIDLE: {
if (wParam == MSGF_MENU) {//表示为菜单消息,当wParam为MSGF_DIALOGBOX表示的是对话框消息
//这里表示菜单进入空闲状态
if (isInitMenu) {
isInitMenu = false;
MENUBARINFO mbi;
memset(&mbi, 0, sizeof(MENUBARINFO));
mbi.cbSize = sizeof(MENUBARINFO);
GetMenuBarInfo((HWND)lParam, OBJID_CLIENT, 0, &mbi);
if (::IsMenu((HMENU)mbi.hMenu)) {
for (int i = 0; i < GetMenuItemCount(mbi.hMenu) - 1; i++) {
MENUITEMINFO menuInfo = GetMenuInfoByPosition(mbi.hMenu, i);
auto aa = menuInfo.dwTypeData;
if (str::Len(menuInfo.dwTypeData)) {
WCHAR menuName[50] = {0};
wcscpy(menuName, menuInfo.dwTypeData);
win::menu::SetText(mbi.hMenu, menuInfo.wID, menuName);
}
}
WCHAR menuStr[50] = {0};
wcscpy(menuStr, L"自定义菜单");
AppendMenu(mbi.hMenu, MF_STRING, (UINT_PTR)9000, menuStr);
}
}
}
} break;
default:
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
参考资料

https://stackoverrun.com/cn/q/1566456 https://docs.microsoft.com/en-us/troubleshoot/cpp/cannot-change-state-menu-item


重要说明

欢迎大家关注我的个人微信公众号,一起探讨和学习C++语言、各种计算机知识、交流职场心得,以及您想了解的各种程序员相关的知识与心得! 在这里插入图片描述


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/siyacaodeai/article/details/112689376

随机推荐

安装centos 系统基础知识

磁盘分区安装一个高性能的centos7.5如同安装了一个全新的windows一样,都需要对磁盘进行分区,本人通过书籍给用户推荐比较合理的静态分区方案,一方面静...

付静永 阅读(109)

python编写函数add求和_Python 100 例

一、Python基础62例1十转二将十进制转换为二进制:>>>bin(10)'0b1010'2十转八十进制转换为八进制:>>&...

weixin_39748928 阅读(860)