How can i modify the context menu of a CEdit control?
Before Windows 7 the solution was easy. Just add your own menu and write your own "Undo,Redo,Cut,Copy,Paste,Delete,Select All" menu items. But now this 开发者_如何学Gois not possible anymore because the menu has became really complex with the unicode and input message stuff.
You need to subclass the edit control then use a hook, following is an example code:
First is to subclass the edit control, usually in the WndProc
:
LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_CREATE:
{
HANDLE m_editControl; /* Supposing it is created */
SetWindowSubclass(m_editControl, EditSubclassProc, 0, NULL);
}
break;
default:
/* default message handling */
}
}
Then in the subclass function:
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;
}
Okay i found how to do it
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
}
}
}
Unfortunately this does not work because the code uses TrackPopupMenu
with the TPM_RETURNCMD
and TPM_NONOTIFY
flags. So you can add new menu items but there is no way to handle the commands. Bad Microsoft, very bad design.
精彩评论