I'm trying to implement IContextMenu, but I'm having some difficulties. In the QueryContextMenu
method I add the menu like this:
HRESULT QueryContextMenu(
HMENU hmenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags
)
{
if (uFlags & CMF_DEFAULTONLY)
{
return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
}
HMENU hSubMenu1 = CreatePopupMenu();
AppendMenu(hSubMenu1, MF_STRING, idCmdFirst + 1, L"Submenu Item 1");
AppendMenu(hSubMenu1, MF_STRING, idCmdFirst + 2, L"Submenu Item 2");
AppendMenu(hmenu, MF_STRING | MF_POPUP, (UINT_PTR)hSubMenu1, L"Top-level menu");
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 3);
}
Now when the user selects a menu item, I need to perform the appropriate actions in the InvokeCommand
method. For now, I determine the selected menu item like this:
HRESULT InvokeCommand(
CMINVOKECOMMANDINFO* pici
)
{
auto selectedMenuID = LOWORD(pici->lpVerb); // 1 or 2
return S_OK;
}
Regarding the above code I have the following questions:
In the
InvokeCommand
method, the menu ID is defined asauto selectedMenuID = LOWORD(pici->lpVerb)
. How reliable is this approach? I haven't found a clear definition for this in the documentation. Should I also check LOWORD forlpVerbW
orlpVerb
is sufficient?Some
IContextMenu
implementations implement adding a submenu not in theQueryContextMenu
method, but in theIContextMenu3::HandleMenuMsg2
method (by handlingWM_INITMENUPOPUP
message). It turns out that we have two ways to add a submenu. How to choose the right way to add a submenu? What should you pay attention to in this case?
I'm trying to implement IContextMenu, but I'm having some difficulties. In the QueryContextMenu
method I add the menu like this:
HRESULT QueryContextMenu(
HMENU hmenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags
)
{
if (uFlags & CMF_DEFAULTONLY)
{
return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
}
HMENU hSubMenu1 = CreatePopupMenu();
AppendMenu(hSubMenu1, MF_STRING, idCmdFirst + 1, L"Submenu Item 1");
AppendMenu(hSubMenu1, MF_STRING, idCmdFirst + 2, L"Submenu Item 2");
AppendMenu(hmenu, MF_STRING | MF_POPUP, (UINT_PTR)hSubMenu1, L"Top-level menu");
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 3);
}
Now when the user selects a menu item, I need to perform the appropriate actions in the InvokeCommand
method. For now, I determine the selected menu item like this:
HRESULT InvokeCommand(
CMINVOKECOMMANDINFO* pici
)
{
auto selectedMenuID = LOWORD(pici->lpVerb); // 1 or 2
return S_OK;
}
Regarding the above code I have the following questions:
In the
InvokeCommand
method, the menu ID is defined asauto selectedMenuID = LOWORD(pici->lpVerb)
. How reliable is this approach? I haven't found a clear definition for this in the documentation. Should I also check LOWORD forlpVerbW
orlpVerb
is sufficient?Some
IContextMenu
implementations implement adding a submenu not in theQueryContextMenu
method, but in theIContextMenu3::HandleMenuMsg2
method (by handlingWM_INITMENUPOPUP
message). It turns out that we have two ways to add a submenu. How to choose the right way to add a submenu? What should you pay attention to in this case?
1 Answer
Reset to default 3There is no
lpVerbW
field inCMINVOKECOMMANDINFO
. To accesslpVerbW
, you have to castpici
toCMINVOKECOMMANDINFOEX*
first (if thecbSize
is large enough). But even then,lpVerbW
is only meaningful if thefMask
field contains theCMIC_MASK_UNICODE
flag. And only if yourGetCommandString()
implementation reports Unicode verbs. If you are using only menu offsets, or non-Unicode verbs, thenlpVerb
will suffice. However, you should useIS_INTRESOURCE()
to decide whether to applyLOWORD()
tolpVerb
. The use oflpVerb
vslpVerbW
is covered in the documentation:How to Implement the IContextMenu Interface: IContextMenu::InvokeCommand Method
Menu items should be added by
QueryContextMenu()
only. This allows the Shell as well as applications to query and invoke commands without actually displaying the menu visually.IContextMenu3
was introduced to support owner-drawing of menu items when they are displayed visually.
IExplorerCommand::EnumSubCommands
to show the submenu. Maybe you have an example of how to implement a submenu inIExplorerCommand
? All examples on the Internet that I found returnE_NOTIMPL
in EnumSubCommands – Joe J Commented Mar 21 at 16:37IExplorerCommand
should be posted separately, as they don't apply to this post regardingIContextMenu
. – Remy Lebeau Commented Mar 21 at 17:48