Я пытаюсь создать функциональность контекстных меню оболочки, несмотря на то, что они заблокированы групповой политикой без реальной причины. Одна вещь, которую это требует, состоит в том, какой значок пользователь фактически щелкает правой кнопкой мыши, или если они просто щелкают по рабочему столу. То же самое относится и к окнам проводника, хотя я планирую запустить на рабочем столе.
До сих пор я мог получить контекстное меню, чтобы показать для определенного файла с буквальным путем. Я нашел хороший список интерфейсов на 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
}
Любая помощь очень ценится.