2013-08-10 3 views
0

파일에 대한 셸 상황에 맞는 메뉴를 표시하려고합니다 (탐색기에서 해당 파일을 마우스 오른쪽 단추로 클릭 할 때와 동일 함). 나는 하나의 파일/폴더에 대해 그렇게 할 수 있었다. 나의 코드는 아래에있다. 이제 Explorer에서 몇 가지를 선택하고 클릭 한 것처럼 파일 목록에 대한 상황에 맞는 메뉴를 호출하려면 어떻게해야합니까?프로그래밍 방식으로 여러 파일에 대해 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; 
} 

답변

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

GetUIObjectOf 함수 PIDLs의 배열 걸린다. 이 함수 호출에서 1은 배열에 항목이 하나만 포함되어 있음을 나타내지 만 같은 방법으로 여러 개의 자식 PIDL을 전달할 수 있습니다. 예 :

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

(실제로는 배열을 동적으로 작성합니다.) 항목은 모두 동일한 상위 폴더의 하위 항목이어야합니다.

+0

감사합니다. 작동합니다. 그것은 내가 메모리 누수가있는 것 같지만. 인터페이스 클래스와는 별도로 어떤 객체를 릴리즈해야하며'SHParseDisplayName'이 리턴하는'ITEMIDLIST'는 무엇입니까? –

+0

누수가 있다고 생각하는 이유는 무엇입니까? 네가 보여준 코드에서 누수가 보이지 않는다. –