在作windows下的C++客户端程序开发的时候,常常会遇到自定义右键菜单的功能点的开发。
这时候,咱们通常只须要在窗口的事件过程当中处理WM_CONTEXTMENU消息。处理时,根据须要能够使用CreatePopupMenu建立弹出菜单,并插入指定的子菜单项,最后处理对应菜单项的消息这样的流程来实现一个自定义的右键菜单列表。也能够经过拿到菜单项的句柄,枚举并修改菜单列表的形式重载一些已经实现的或者已经定义的菜单列表。
以前遇到一个需求,须要继承Edit默认的右键菜单,在此基础上添加一些自定义的右键菜单项。然而,按照以前的理解,写代码的过程当中发现,WM_CONTEXTMENU消息触发的时候,不能获取到默认的右键菜单句柄信息,也就拿不到右键菜单中的菜单列表条目。所以也不能继续进行右键菜单项的自定义操做。下面用代码演示一下,通常自定义右键菜单的方法和在editbox中实现重载默认Context的方法。windows
在这里用代码表示通常的右键菜单建立和处理的过程:后端
//编辑框事件处理 #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...
https://docs.microsoft.com/en...微信
==欢欢迎你们关注个人我的微信公众号,一块儿探讨和学习C++后端、客户端的开发知识!==学习