本文主要是介绍C++ 重载EditBox默认ContextMenu(含详细代码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本人微信公众号:CPP进阶之旅
如果觉得这篇文章对您有帮助,欢迎关注 “CPP进阶之旅” 学习更多技术干货
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++ 重载EditBox默认ContextMenu(含详细代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!