我知道当你有一个IShellItem对象时如何添加shell上下文菜单。基本程序是:
示例代码:
//I've right-clicked something that represents one shell item.
//Make a context menu appear appropriate for that item
//Get the IContextMenu handler for this shell item
IContextMenu contextMenu;
HRESULT hr = shellItem.BindToHandler(null, BHID_SFUIObject, IContextMenu, out contextMenu);
OleCheck(hr);
//Create a popup menu
HMENU menu = CreatePopupMenu();
if (menu == 0) ThrowLastError();
//Have the shell IContextMenu stuff things into our hmenu
hr = contextMenu.QueryContextMenu(menu, 0, 1, 0x7FFF, CMF_EXPLORE || CMF_ITEMMENU);
OleCheck(hr);
//Now we can show the context menu
TrackPopupMenu(menu, TPM_LEFTALIGN || TPM_LEFTBUTTON || TPM_RIGHTBUTTON || TPM_RETURNCMD, pos.X, pos.Y, 0, callbackWindow, null);
和viola;显示所选IShellItem的shell上下文菜单:
如果我选择多个项目,我的代码(根据定义)仍然只能理解一个shell项目:
我怎么能处理多个贝壳项目?我知道让shell填充菜单的唯一方法就是当你有一个shell项时。
我如何要求shell创建一个IContextMenu,或者填充一次HMENU,这是多个项目?
shell可以显示适用于来自不同文件夹的项目的上下文菜单:
您需要使用IShellItemArray界面,这样两个项目:
// get two Shell Items and get their respective absolute PIDLs
CComPtr<IShellItem> item1;
HRCHECK(SHCreateItemFromParsingName(L"c:\\myPath1\\myFile1.myExt1", NULL, IID_PPV_ARGS(&item1)));
CComQIPtr<IPersistIDList> idl1(item1);
CComHeapPtr<ITEMIDLIST_ABSOLUTE> spidl1;
HRCHECK(idl1->GetIDList(&spidl1));
CComPtr<IShellItem> item2;
HRCHECK(SHCreateItemFromParsingName(L"c:\\myPath2\\myFile2.myExt2", NULL, IID_PPV_ARGS(&item2)));
CComQIPtr<IPersistIDList> idl2(item2);
CComHeapPtr<ITEMIDLIST_ABSOLUTE> spidl2;
HRCHECK(idl2->GetIDList(&spidl2));
// build a Shell Item Array from them
LPCITEMIDLIST list[2];
list[0] = spidl1;
list[1] = spidl2;
CComPtr<IShellItemArray> array;
HRCHECK(SHCreateShellItemArrayFromIDLists(2, list, &array));
// get the menu object
CComPtr<IContextMenu> menu;
HRCHECK(array->BindToHandler(NULL, BHID_SFUIObject, IID_PPV_ARGS(&menu)));
// ... etc ...
HMENU hMenu= CreatePopupMenu();
HRCHECK(menu->QueryContextMenu(hMenu, 0, 1, 0x7FFF, CMF_EXPLORE || CMF_ITEMMENU));
通常,您不必创建数组,如在复制粘贴或拖放操作,或上下文菜单打开调用(命名空间扩展等)中,数组存在于剪贴板或数据对象中传入
我找到了你不能使用的原因:
shellItem.BindToHandler(null, BHID_SFUIObject, IContextMenu, out contextMenu);
获取来自不同文件夹的项目的IContextMenu
。它在BindToHandler
的文档中被提到:
Beedh_sfyybjekt
限制使用
GetUIObjectOf
。仅将此处理程序类型用于平面项目数组,其中所有项目都在同一文件夹中
1强调我的
但这并没有阻止Windows自己的搜索结果,以及Jam-Software的UltraSearch这样做:
所以一定是可能的。
但这与另一个答案的一部分回答了这个问题。