如何为多个shell项(而不是单个IShellItem)填充上下文菜单

问题描述 投票:0回答:2

我知道当你有一个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上下文菜单:

enter image description here

但是如何为多个IShellItem做到这一点

如果我选择多个项目,我的代码(根据定义)仍然只能理解一个shell项目:

enter image description here

我怎么能处理多个贝壳项目?我知道让shell填充菜单的唯一方法就是当你有一个shell项时。

我如何要求shell创建一个IContextMenu,或者填充一次HMENU,这是多个项目?

Bonus

shell可以显示适用于来自不同文件夹的项目的上下文菜单:

enter image description here

Bonus Reading

shell winapi com windows-shell
2个回答
2
投票

您需要使用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));

通常,您不必创建数组,如在复制粘贴或拖放操作,或上下文菜单打开调用(命名空间扩展等)中,数组存在于剪贴板或数据对象中传入


0
投票

我找到了你不能使用的原因:

shellItem.BindToHandler(null, BHID_SFUIObject, IContextMenu, out contextMenu);

获取来自不同文件夹的项目的IContextMenu。它在BindToHandler的文档中被提到:

Beedh_sfyybjekt

限制使用GetUIObjectOf。仅将此处理程序类型用于平面项目数组,其中所有项目都在同一文件夹中

1强调我的

但这并没有阻止Windows自己的搜索结果,以及Jam-Software的UltraSearch这样做:

enter image description here

enter image description here

所以一定是可能的。

但这与另一个答案的一部分回答了这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.