如何使用 Windows API 枚举 shell 上下文菜单项?我需要用纯C来做。
问问题
1272 次
3 回答
1
您需要完全按照 Explorer 所做的那样:对于有问题的项目(文件、文件夹、其他 shell 命名空间位置),您需要确定 shell 扩展列表。这些是 COM 类,它们实现IContextMenu
接口。对于每个适用的 shell 扩展,您可以提供自己的菜单并请求此类扩展(处理程序)使用其附加项()填充菜单IContextMenu::QueryContextMenu
。
稍后您可以自由决定何时、何地以及是否要弹出此菜单。如果需要处理这些附加处理程序的命令之一,您有责任通过 将命令转发给处理程序IContextMenu::InvokeCommand
。如果您出于某种原因更喜欢自动化某些命令并在不弹出菜单的情况下调用它,您也可以这样做。
您可能感兴趣的链接:
于 2012-07-05T15:15:36.340 回答
1
如果您想显示菜单或仅枚举项目,我有点不清楚,后者是这样做的(不包括子菜单)
HRESULT GetContextMenuForFSItem(PCTSTR path,IContextMenu**ppCM)
{
PIDLIST_ABSOLUTE pidlAbs;
HRESULT hr = SHParseDisplayName(path,0,&pidlAbs,0,0);
if (!hr)
{
IShellFolder*pSF;
PCUITEMID_CHILD pidlLast;
hr = SHBindToParent(pidlAbs,&IID_IShellFolder,(void**)&pSF,&pidlLast);
if (!hr)
{
hr = pSF->lpVtbl->GetUIObjectOf(pSF,0,1,&pidlLast,&IID_IContextMenu,0,(void**)ppCM);
pSF->lpVtbl->Release(pSF);
}
ILFree(pidlAbs);
}
return hr;
}
int main()
{
CoInitialize(0);
WCHAR buf[MAX_PATH];
GetWindowsDirectory(buf,MAX_PATH); /* Arbitrary filesystem item */
IContextMenu*pCM;
HRESULT hr = GetContextMenuForFSItem(buf,&pCM);
if (!hr)
{
HMENU hMenu = CreatePopupMenu();
hr = pCM->lpVtbl->QueryContextMenu(pCM,hMenu,0,1,0x7fff,0);
if (hr > 0)
{
UINT c=GetMenuItemCount(hMenu), i=0;
for (; i<c; ++i)
{
GetMenuString(hMenu,i,buf,MAX_PATH,MF_BYPOSITION);
if (GetMenuState(hMenu,i,MF_BYPOSITION)&MF_SEPARATOR) lstrcpy(buf,_T("--separator--"));
printf("%.2u=%ws\n",i,buf);
/*
Call IContextMenu::GetCommandString to get the verb
or IContextMenu::InvokeCommand to execute
*/
}
}
pCM->lpVtbl->Release(pCM);
DestroyMenu(hMenu);
}
CoUninitialize();
return 0;
}
在我的系统上打印:
00=&Open
01=--separator--
02=S&hare with
03=Restore previous &versions
04=&Include in library
05=--separator--
06=Se&nd to
07=--separator--
08=Cu&t
09=&Copy
10=--separator--
11=Create &shortcut
12=&Delete
13=--separator--
14=P&roperties
在 C 中使用 COM 并不好玩,如果可以的话,请切换到 C++...
于 2012-07-05T20:18:24.463 回答
0
Raymond Chen 写了一个十一部分系列来解释如何做到这一点。这真的不简单。
于 2012-07-05T15:08:44.960 回答