打开Windows资源管理器Shell上下文菜单

时间:2012-07-05 14:57:04

标签: c winapi windows-shell

如何使用Windows API枚举shell上下文菜单项?我需要在纯粹的C中做到这一点。

3 个答案:

答案 0 :(得分: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 ++ ......

答案 1 :(得分:0)

Raymond Chen写了一篇eleven part series来解释如何做到这一点。这真的不是直截了当的。

答案 2 :(得分:0)

您需要完成资源管理器所做的事情:对于有问题的项目(文件,文件夹,其他shell命名空间位置),您可以识别shell扩展名列表。这些是COM类,它们实现IContextMenu接口。对于适用的每个shell扩展,您可以提供自己的菜单,并请求此类扩展(处理程序)使用其附加项(IContextMenu::QueryContextMenu)填充菜单。

稍后您可以自由决定何时,何地以及是否要弹出此菜单。如果需要处理其中一个附加处理程序的命令,您有责任通过IContextMenu::InvokeCommand将命令发送给处理程序。如果您出于某种原因喜欢自动执行某个命令并在不弹出菜单的情况下调用它,那么您也可以这样做。

您可能感兴趣的链接: