Why am I not receiving the WM_MENUCHAR message?

I have implemented an interface IContextMenu3and I am trying to capture keystrokes for my own accelerator. The problem is that if I hover over my submenu in the root menu, I did not receive any messages WM_MENUCHAR, whereas if I hover over a submenu inside one of my submenus, then I will do it.

I know that a message is WM_INITMENUPOPUPsent only if there is a child. WM_MENUCHARhas the reservation that no accelerators are associated with a key. I know that this is a caution to be taken when I press a key, I get a sound “no accelerator”.

Is there another clause that I don't know about?

This is the smallest code I can get that reproduces the problem:


HRESULT CFolderViewImplContextMenu::QueryContextMenu(HMENU hmenu, UINT uMenuIndex, UINT idCmdFirst, UINT idCmdLast, UINT /* uFlags */)
{
UINT uID = idCmdFirst;
HMENU hSubmenu = CreatePopupMenu();

MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_SUBMENU | MIIM_ID | MIIM_STRING;
mii.dwTypeData = str_toWchar("test");
mii.wID = uID++;
mii.hSubMenu = hSubmenu;    

InsertMenuItem ( hmenu, 0, TRUE, &mii );
InsertMenu ( hSubmenu, 0, MF_BYPOSITION, uID++, L"&Notepad" );
InsertMenu ( hSubmenu, 1, MF_BYPOSITION , uID++, L"&Internet Explorer" );

HMENU hSubmenu2 = CreatePopupMenu();
MENUITEMINFO mii2 = {0};
mii2.cbSize = sizeof(MENUITEMINFO);

mii2.fMask  = MIIM_ID | MIIM_TYPE | MIIM_SUBMENU;
mii2.fType  = MFT_OWNERDRAW;
mii2.wID    = uID++;
mii2.hSubMenu = hSubmenu2;
InsertMenuItem ( hSubmenu, 0, TRUE, &mii2 );

InsertMenuA ( hSubmenu2, 0, MF_BYPOSITION, uID++, "");

return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, uID - idCmdFirst );
}
+3
source share
3 answers

The problem is the first item in the submenu. If the first item in the submenu is also a submenu, the message is not transmitted. So I instead placed a regular item there.

0
source

WM_MENUCHARredirected only for submenus. (It cannot be redirected to top-level menu items because it will be Catch-22. You want to redirect it to the context menu handler for the menu item the key corresponds to, but you cannot do this until you answer WM_MENUCHAR!)

+4
source

How about this: If you are processing IContextMenu3 messages, and therefore WM_DRAWITEM, you can use WindowFromDC () to get the HWND menu window from WM_DRAWITEM, then subclass it and catch WM_KEYDOWN or do whatever you like. I tried (did some other things than this) and it works.

+2
source

All Articles