3

我实现了一个IContextMenu3界面,并试图为我自己的自定义加速器捕获击键。问题是,如果我将鼠标悬停在根菜单中的子菜单上,我不会收到任何WM_MENUCHAR消息,而如果我将鼠标悬停在其中一个子菜单内的子菜单上,那么我会收到。

我知道WM_INITMENUPOPUP只有在有孩子的情况下才会发送消息。有WM_MENUCHAR一个警告,没有加速器绑定到键。我知道要注意这一点,因为当我按下一个键时,我会听到独特的“无加速器”哔声。

还有另一个我不知道的警告吗?

这是我能得到的重现问题的最小代码:


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

3 回答 3

4

WM_MENUCHAR仅为子菜单转发。(它不能为顶级菜单项转发,因为那将是 Catch-22。您希望将其转发到键对应的菜单项的上下文菜单处理程序,但您不能这样做直到你有答案WM_MENUCHAR!)

于 2012-05-02T21:49:33.100 回答
2

怎么样:如果您正在处理 IContextMenu3 消息,因此是 WM_DRAWITEM,您可以使用 WindowFromDC() 从 WM_DRAWITEM 获取菜单窗口的 HWND,然后将其子类化并捕获 WM_KEYDOWN 或做任何您喜欢的事情。我试过了(正在做一些其他的事情)并且它有效。

于 2012-10-04T18:57:31.303 回答
0

问题是子菜单中的第一项。如果子菜单中的第一项也是子菜单,则消息不会通过。所以我把一个普通的物品放在那里。

于 2012-05-03T21:09:33.697 回答