I'm installing a hook within my application to get the standard EDIT context menu (with undo/copy/edit/paste/etc.). I need to insert a new menu item for my application.
I've set a windows hook, but I can't seem to get the HMENU for the context menu. This is where I set the hook:
g_hHook = SetWindowsHookEx(WH_CALLWNDPROC, HookCallWndProc, NULL, GetCurrentThreadId());
Here is my callback function:
LRESULT CALLBACK HookCallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
LPCWPSTRUCT cwps = (LPCWPSTRUCT)lParam;
switch(cwps->message)
{
case WM_CREATE:
{
WCHAR szClass[128];
GetClassName(cwps->hwnd, szClass, 127);
if (wcscmp(szClass, L"#32768") == 0)
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)cwps->lParam;
HMENU hMenu = GetMenu(cwps->hwnd);
// hMenu is 0x0
//MENUINFO info;
//ZeroMemory(&info, sizeof(MENUINFO));
//info.cbSize = sizeof(info);
//GetMenuInfo(hMenu, &info);
MessageBox(NULL, L"Test", L"Test", NULL);
}
break;
}
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
I also tried setting the hook with WH_CALLWNDPROCRET, but this one doesn't even capture the WM_CREATE message for the menu.
Does anyone know how to obtain the HMENU for this particular situation?
Thanks, Kevin
You can send the MN_GETHMENU message to get the HMENU:
case WM_CREATE:
{
WCHAR szClass[128];
GetClassName(cwps->hwnd, szClass, 127);
if (wcscmp(szClass, L"#32768") == 0)
{
// Must delay MN_GETHMENU...
PostMessage(g_hDlg,WM_APP,(WPARAM)cwps->hwnd,(LPARAM)HookCallWndProc);
}
break;
}
...
LRESULT CALLBACK MyWindow(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
{
switch(msg)
{
case WM_APP:
if (lp == (LPARAM)HookCallWndProc) // Just making sure it is our special message
{
HMENU hMenu = (HMENU) SendMessage((HWND)wp,MN_GETHMENU,0,0);
if (hMenu)
{
AppendMenu(hMenu,MF_STRING,666,L"Hello SO");
}
}
break;
This is a bit hacky but hacks are pretty much unavoidable when customizing controls like this...