Получить Desktop PIDL от Координаты - PullRequest
3 голосов
/ 07 марта 2012

Я пытаюсь создать функциональность контекстных меню оболочки, несмотря на то, что они заблокированы групповой политикой без реальной причины. Одна вещь, которую это требует, состоит в том, какой значок пользователь фактически щелкает правой кнопкой мыши, или если они просто щелкают по рабочему столу. То же самое относится и к окнам проводника, хотя я планирую запустить на рабочем столе.

До сих пор я мог получить контекстное меню, чтобы показать для определенного файла с буквальным путем. Я нашел хороший список интерфейсов на msdn , но ни один из связанных с десктопом, который я мог найти, не имел никакого способа получить элемент рабочего стола, подобный этому. Самое близкое совпадение, которое я смог найти, было IActiveDesktop :: GetDesktopItem , при котором нужно было пройти через каждый отдельный элемент и посмотреть, совпадает ли позиция, а затем предположить, что ни одна из них не была нажата, если ни одна не совпадает.

Однако этот подход поднимает две новые проблемы. Во-первых, я не уверен, как пройти через каждую иконку. Во-вторых, я понятия не имею, как преобразовать это в PIDL.

Кроме того, даже если бы у меня работали значки, как бы я расширил это до контекстного меню оболочки только для рабочего стола?

Вот код, который я использую для определенного файла:

#define _WIN32_WINNT _WIN32_WINNT_WINXP //going to be using on XP, tested on 7
#include <windows.h> //main header
#include <shellapi.h> //shell headers
#include <shlobj.h>

#include "G:\programming\v1\winwrap.h" //used for the window to display menu on

LPCONTEXTMENU cm; //holds context menu

msgproc (rproc) //this is called when right mouse button is depressed on window
{
    //This function shows the context menu of the program on this window
    //hwnd() is the HWND of the window involved with the right click
    HMENU hMenu = CreatePopupMenu(); 
    DWORD Flags = CMF_EXPLORE;
    cm->QueryContextMenu(hMenu, 0, 1, 0x7FFF, Flags);

    POINT pt;
    GetCursorPos(&pt);
    int Cmd = TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hwnd(), 0);

    CMINVOKECOMMANDINFO ci;

    if (Cmd)
    {
        ci.lpVerb = MAKEINTRESOURCE(Cmd - 1);
        ci.lpParameters = "";
        ci.lpDirectory = "";
        ci.nShow = SW_SHOWNORMAL;
        cm->InvokeCommand(&ci);
    }
}

int main()
{
    Window win; //create window for menu to go on, can be invisible, fullscreen later
    win.addmsg (WM_RBUTTONUP, rproc); //handle message with previous function

    WCHAR fname [MAX_PATH] = L"C:\\Users\\Chris\\Desktop\\context.exe"; //full path
    WCHAR path [MAX_PATH] = L"C:\\Users\\Chris\\Desktop"; //path part
    WCHAR name [MAX_PATH] = L"context.exe"; //filename part

    LPSHELLFOLDER desktopFolder; //get desktop shell folder
    SHGetDesktopFolder (&desktopFolder);

    LPITEMIDLIST pidl; //tried using this for no icon by changing GetUIObjectOf to this pild to no avail
    DWORD eaten;

    desktopFolder->ParseDisplayName (0, 0, path, &eaten, &pidl, 0);

    LPSHELLFOLDER parent;
    desktopFolder->BindToObject (pidl, 0, IID_IShellFolder, (void **)&parent);

    LPITEMIDLIST localPidl; //file pidl
    parent->ParseDisplayName (0, 0, name, &eaten, &localPidl, 0);

    parent->GetUIObjectOf (0, 0, (LPCITEMIDLIST *)&localPidl, IID_IContextMenu, 0, (void **)&cm); //gets context menu

    messageLoop(); //window message loop
}

Любая помощь очень ценится.

...