Why do I not receive the WM_MENUCHAR message?

I implemented an IContextMenu3 interface and I am trying to capture keystrokes for my own custom accelerator. The problem is that if i hover over my submenu in the root menu I dont get any WM_MENUCHAR messages whereas if I hover over a submenu that is inside one of my submenu's then I do.

I know that the WM_INITMENUPOPUP message only gets sent if there is a child. The WM_MENUCHARhas the caveat that no accelerators are bound to the key. I know this caveat to be held since when I press a key, I get the distinctive 'no-accelerator' beep.

Is there another caveat that I am not aware of?

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 );
}

Answers


WM_MENUCHAR is forwarded only for submenus. (It can't be forwarded for top-level menu items because that would be a Catch-22. You want to forward it to the context menu handler for the menu item that the the key corresponds to, but you can't do that until you have the answer to WM_MENUCHAR!)


How about this: If you are handling IContextMenu3 messages, consequently WM_DRAWITEM, you can use WindowFromDC() to get menu window's HWND from WM_DRAWITEM, then subclass it and catch WM_KEYDOWN or do whatever you like with it. I tried it (was doing some other stuff than this) and it works.


The problem is the first item in the submenu. If the first item in the submenu is also a submenu, then the message doesnt get passed. So I instead put a normal item there.


Need Your Help

UIPopoverController, backgroundColor = clearColor

iphone uipopovercontroller uicolor

I had a UITableView that I replaced with a UIPopoverController. My UITableView's background was set to clearColor and it showed the custom background through the table. The table cells also match...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.