Вызов меню оболочки Windows (аналогично щелчку правой кнопкой мыши в Проводнике) для нескольких файлов программно

Я пытаюсь отобразить контекстное меню оболочки для файла (так же, как когда я щелкаю правой кнопкой мыши по этому файлу в Проводнике) программно. Мне удалось сделать это для одного файла / папки, мой код ниже. Теперь, как я могу вызвать контекстное меню для списка файлов, как будто я выбрал пару в Проводнике и щелкнул по ним?

bool openShellContextMenuForObject(const std::wstring &path, int xPos, int yPos, void * parentWindow)
{
assert (parentWindow);
ITEMIDLIST * id = 0;
std::wstring windowsPath = path;
std::replace(windowsPath.begin(), windowsPath.end(), '/', '\\');
HRESULT result = SHParseDisplayName(windowsPath.c_str(), 0, &id, 0, 0);
if (!SUCCEEDED(result) || !id)
return false;
CItemIdListReleaser idReleaser (id);

IShellFolder * ifolder = 0;

LPCITEMIDLIST idChild = 0;
result = SHBindToParent(id, IID_IShellFolder, (void**)&ifolder, &idChild);
if (!SUCCEEDED(result) || !ifolder)
return false;
CComInterfaceReleaser ifolderReleaser (ifolder);

IContextMenu * imenu = 0;
result = ifolder->GetUIObjectOf((HWND)parentWindow, 1, (const ITEMIDLIST **)&idChild, IID_IContextMenu, 0, (void**)&imenu);
if (!SUCCEEDED(result) || !ifolder)
return false;
CComInterfaceReleaser menuReleaser(imenu);

HMENU hMenu = CreatePopupMenu();
if (!hMenu)
return false;
if (SUCCEEDED(imenu->QueryContextMenu(hMenu, 0, 1, 0x7FFF, CMF_NORMAL)))
{
int iCmd = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, xPos, yPos, (HWND)parentWindow, NULL);
if (iCmd > 0)
{
CMINVOKECOMMANDINFOEX info = { 0 };
info.cbSize = sizeof(info);
info.fMask = CMIC_MASK_UNICODE;
info.hwnd = (HWND)parentWindow;
info.lpVerb  = MAKEINTRESOURCEA(iCmd - 1);
info.lpVerbW = MAKEINTRESOURCEW(iCmd - 1);
info.nShow = SW_SHOWNORMAL;
imenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
}
}
DestroyMenu(hMenu);

return true;
}

0

Решение

result = ifolder->GetUIObjectOf((HWND)parentWindow, 1, (const ITEMIDLIST **)&idChild, IID_IContextMenu, 0, (void**)&imenu);

GetUIObjectOf функция занимает массив PIDL. 1 в этом вызове функции указывает, что ваш массив содержит только 1 элемент, но вы можете передать любое количество дочерних PIDL, используя один и тот же метод. Например.:

LPITEMIDLIST pidlArray[3] = { pidl1, pidl2, pidl3 };
result = ifolder->GetUIObjectOf((HWND)parentWindow, _countof(pidlArray), pidlArray, IID_IContextMenu, 0, (void**)&imenu);

(В реальном мире вы бы строили свой массив динамически). Обратите внимание, что все элементы должны быть дочерними для одной родительской папки.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector