我正在尝试创建shell上下文菜单的功能,尽管它们被组策略阻止,没有任何实际原因。这需要的一件事是用户实际右键单击的图标,或者他们只是单击桌面。同样的事情也适用于资源管理器窗口,虽然桌面是我计划启动的地方。
到目前为止,我可以获取上下文菜单,以显示具有文字路径的特定文件。我在msdn找到了一个很好的接口列表,但是我找不到任何与桌面相关的接口都没有办法获得这样的桌面项目。我能找到的最接近的匹配是IActiveDesktop::GetDesktopItem,它遍历每一个项目并查看位置是否匹配,然后假设没有一个匹配,如果没有匹配。
但这种方法提出了两个新问题。首先,我不确定如何浏览每个图标。其次,我不知道如何将其转换为PIDL。
此外,即使我的图标工作,我如何将其扩展到桌面的shell上下文菜单?
以下是我用于特定文件的代码:
#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
}
非常感谢任何帮助。