我想编写以下的过程/函数:
procedure ShowSysPopup(aFile: string; x, y: integer);
这将构建并显示(在坐标x和y处)Windows资源管理器中给定文件所见的右键菜单。我对“显示”部分不是很感兴趣,而是更关注如何构建这样的菜单。
我为您提供了一个快速的解决方案。 将这些单元添加到“Uses”部分:
... ShlObj, ActiveX, ComObj
以下是您的过程,我只是添加了一个新的参数“HND”,以携带TWinControl的句柄,您将使用它来显示上下文菜单。
procedure ShowSysPopup(aFile: string; x, y: integer; HND: HWND);
var
Root: IShellFolder;
ShellParentFolder: IShellFolder;
chEaten,dwAttributes: ULONG;
FilePIDL,ParentFolderPIDL: PItemIDList;
CM: IContextMenu;
Menu: HMenu;
Command: LongBool;
ICM2: IContextMenu2;
ICI: TCMInvokeCommandInfo;
ICmd: integer;
P: TPoint;
Begin
OleCheck(SHGetDesktopFolder(Root));//Get the Desktop IShellFolder interface
OleCheck(Root.ParseDisplayName(HND, nil,
PWideChar(WideString(ExtractFilePath(aFile))),
chEaten, ParentFolderPIDL, dwAttributes)); // Get the PItemIDList of the parent folder
OleCheck(Root.BindToObject(ParentFolderPIDL, nil, IShellFolder,
ShellParentFolder)); // Get the IShellFolder Interface of the Parent Folder
OleCheck(ShellParentFolder.ParseDisplayName(HND, nil,
PWideChar(WideString(ExtractFileName(aFile))),
chEaten, FilePIDL, dwAttributes)); // Get the relative PItemIDList of the File
ShellParentFolder.GetUIObjectOf(HND, 1, FilePIDL, IID_IContextMenu, nil, CM); // get the IContextMenu Interace for the file
if CM = nil then Exit;
P.X := X;
P.Y := Y;
Windows.ClientToScreen(HND, P);
Menu := CreatePopupMenu;
try
CM.QueryContextMenu(Menu, 0, 1, $7FFF, CMF_EXPLORE or CMF_CANRENAME);
CM.QueryInterface(IID_IContextMenu2, ICM2); //To handle submenus.
try
Command := TrackPopupMenu(Menu, TPM_LEFTALIGN or TPM_LEFTBUTTON or TPM_RIGHTBUTTON or
TPM_RETURNCMD, p.X, p.Y, 0, HND, nil);
finally
ICM2 := nil;
end;
if Command then
begin
ICmd := LongInt(Command) - 1;
FillChar(ICI, SizeOf(ICI), #0);
with ICI do
begin
cbSize := SizeOf(ICI);
hWND := 0;
lpVerb := MakeIntResourceA(ICmd);
nShow := SW_SHOWNORMAL;
end;
CM.InvokeCommand(ICI);
end;
finally
DestroyMenu(Menu)
end;
End;
像这样修改/添加初始化和结束部分
initialization
OleInitialize(nil);
finalization
OleUninitialize;
以下是如何使用此过程的方法:
procedure TForm2.Button1Click(Sender: TObject);
begin
ShowSysPopup(Edit1.Text,Edit1.Left,Edit1.Top, Handle);
end;
我希望这对你有用。
问候,
编辑:如果你想为多个文件显示上下文菜单,请查看我博客中的这篇文章
虽然我同意Deltics的观点,这是一项艰巨的工作,但大多数(如果不是全部)项目所需的信息都可以在注册表中免费获得。 Deltics答案中列出的指南看起来很好,可以提供大部分项目。 许多内容可以从注册表中的基本条目中查找,而其他内容则需要调用COM对象。
if Supports(nil, IShellCommandVerb, SCV) then
真的很突出。请您也在您的博客上更正代码。不过我的第一条评论仍然有效。 - Sertac AkyuzEdit1.Text := 'C:\'
失败时 - Hanlin