Вам нужно использовать интерфейс 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));
Как правило, вам не нужно создавать массивы, как в операциях копирования, вставки или перетаскивания, или вызовах открытия контекстного меню (расширения пространства имен и т. Д.), Массив присутствует в буфере обмена или в переданный объект данных.