抱歉,这是一个愚蠢的问题,但是我想知道在实现快捷菜单处理程序(IContextMenu
)时是否可以使用菜单模板资源。
如果没有,添加大量菜单项是否仍然被接受?也许用LoadMenuIndirect
?
谢谢您的指导。
当然,使用LoadMenu API获取HMENU,然后使用InsertMenuItem在具有资源指定菜单的顶级弹出窗口上创建一个新项目。
嗯,我想出了一个解决方案,但我愿意接受反馈以改进它。
要做的第一件事就是在Visual Studio中创建菜单模板资源,这是正常方法。但是在Resource.h
标头中,更改自动生成的菜单项ID,以使它们从0开始并相应地递增。这些将是菜单偏移。
[接下来,我创建了一个帮助函数,该函数将从模板中加载菜单并(递归地)将项目ID偏移给定的数字(该数字在idCmdFirst
中为IContextMenu:QueryContextMenu
):
void OffsetMenuIds(HMENU hmenu, UINT idCmdFirst)
{
MENUITEMINFO mii;
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_FTYPE | MIIM_SUBMENU | MIIM_ID;
INT cItems = GetMenuItemCount(hmenu);
for (UINT i = 0; i < cItems; ++i)
{
if (!GetMenuItemInfo(hmenu, i, TRUE, &mii))
{
continue;
}
if (mii.fType & MFT_SEPARATOR)
{
continue;
}
if (mii.hSubMenu)
{
OffsetMenuIds(mii.hSubMenu, idCmdFirst);
continue;
}
mii.wID += idCmdFirst;
SetMenuItemInfo(hmenu, i, TRUE, &mii);
}
}
所以现在,当调用QueryContextMenu
时,我们从资源中加载菜单,调用OffsetMenuIds
函数,然后将模板中的顶级菜单项复制到资源管理器的上下文菜单中:
STDMETHODIMP CFileRightClickHandler::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
HMENU hmenuTemplate = LoadMenu( _AtlBaseModule.GetModuleInstance(),
MAKEINTRESOURCE(IDR_MENU1) );
OffsetMenuIds(hmenuTemplate, idCmdFirst);
INT cItems = GetMenuItemCount(hmenuTemplate);
for (UINT i = 0; i < cItems; ++i)
{
MENUITEMINFO mii;
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_TYPE | MIIM_SUBMENU | MIIM_ID;
mii.dwTypeData = NULL;
CHeapPtr<WCHAR> pszCommand;
if (!GetMenuItemInfo(hmenuTemplate, i, TRUE, &mii))
{
continue;
}
if (mii.fType == MFT_STRING)
{
pszCommand.Allocate(++mii.cch);
mii.dwTypeData = pszCommand;
if (!GetMenuItemInfo(hmenuTemplate, i, TRUE, &mii))
{
continue;
}
}
if (!InsertMenuItem(hmenu, ++indexMenu, TRUE, &mii))
{
continue;
}
}
DestroyMenu(hmenuTemplate);
return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, (USHORT)ID_LAST);
}
这至少处理简单的菜单项。这可能需要扩展以处理更复杂的菜单项,例如带有位图的菜单项。无论如何,请告诉我您是否有任何建议的改进。