3

インターフェイスを実装IContextMenu3し、独自のカスタム アクセラレータのキーストロークをキャプチャしようとしています。問題は、ルート メニューのサブメニューにカーソルを合わせるとWM_MENUCHARメッセージが表示されないのに対し、サブメニューの 1 つにあるサブメニューにカーソルを合わせるとメッセージが表示されることです。

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 に答える