Windows 7 如何修改CEdit控件的上下文菜单?
在windows7之前,解决方案很简单。只需添加您自己的菜单并编写您自己的“撤消、重做、剪切、复制、粘贴、删除、全选”菜单项。但是现在这已经不可能了,因为菜单已经变得非常复杂,包含了unicode和输入消息的内容。好的,我找到了方法Windows 7 如何修改CEdit控件的上下文菜单?,windows-7,mfc,cedit,Windows 7,Mfc,Cedit,在windows7之前,解决方案很简单。只需添加您自己的菜单并编写您自己的“撤消、重做、剪切、复制、粘贴、删除、全选”菜单项。但是现在这已经不可能了,因为菜单已经变得非常复杂,包含了unicode和输入消息的内容。好的,我找到了方法 static bool is_first_time; case WM_CONTEXTMENU: { is_first_time = true; original_window_proc(message,wparam,lparam); break;
static bool is_first_time;
case WM_CONTEXTMENU: {
is_first_time = true;
original_window_proc(message,wparam,lparam);
break;
case WM_ENTERIDLE:
if (wparam == MSGF_MENU) {
if (is_first_time) {
is_first_time = false;
MENUBARINFO mbi;
memset(&mbi, 0, sizeof(MENUBARINFO));
mbi.cbSize = sizeof(MENUBARINFO);
GetMenuBarInfo((HWND)lparam, OBJID_CLIENT, 0, &mbi);
if (::IsMenu((HMENU)mbi.hMenu)) {
.... add your menu items here
}
}
}
不幸的是,这不起作用,因为代码使用带有
TPM\u RETURNCMD
和TPM\u notify
标志的trackpopumpmenu
。因此,您可以添加新的菜单项,但无法处理命令。糟糕的Microsoft,非常糟糕的设计。您需要对编辑控件进行子类化,然后使用钩子,下面是一个示例代码:
LRESULT CALLBACK EditSubclassProc(HWND hWndEdit, UINT Msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIDSubclass, DWORD_PTR dwRefData)
{
LRESULT ret{};
switch (Msg)
{
case WM_CONTEXTMENU:
{
HWINEVENTHOOK hWinEventHook{ SetWinEventHook(EVENT_SYSTEM_MENUPOPUPSTART, EVENT_SYSTEM_MENUPOPUPSTART, NULL,
[](HWINEVENTHOOK hWinEventHook, DWORD Event, HWND hWnd, LONG idObject, LONG idChild, DWORD idEventThread, DWORD dwmsEventTime)
{
if (idObject == OBJID_CLIENT && idChild == CHILDID_SELF)
{
HMENU hMenuContextEdit{ (HMENU)SendMessage(hWnd, MN_GETHMENU, NULL, NULL) };
// Do what you want to do
}
},
GetCurrentProcessId(), GetCurrentThreadId(), WINEVENT_OUTOFCONTEXT) };
ret = DefSubclassProc(hWndEditMessage, Msg, wParam, lParam);
UnhookWinEvent(hWinEventHook);
}
break;
default:
{
ret = DefSubclassProc(hWndEdit, Msg, wParam, lParam);
}
break;
}
return ret;
}
即使我现在无法尝试,也会将其标记为答案。