function ShowShellPopup(HND: HWND; X, Y: Integer; Directory: string; Files: TStringList; var ICmd: Integer; var Verb: string): Boolean;
var Root: IShellFolder;
ShellParentFolder: IShellFolder;
chEaten, dwAttributes: ULONG;
ParentFolderPIDL: PItemIDList;
FilePIDL: array of PItemIDList;
CM: IContextMenu;
Menu: HMenu;
Command: LongBool;
ICM2: IContextMenu2;
ICI: TCMInvokeCommandInfo;
I: Integer;
ZVerb: array[0..255] of AnsiChar;
Handled: Boolean;
SCV: IShellCommandVerb;
HR: HResult;
P: TPoint;
begin
result:=False;
//
OleCheck(SHGetDesktopFolder(Root)); //Get the Desktop IShellFolder interface
//
//wenn alle Files im gleichen Ordner liegen dann ist Directory dieser Ordner
//wenn nicht alle Files im gleichen Ordner liegen dann muss Directory = '' sein
OleCheck(Root.ParseDisplayName(HND, nil,
PWideChar(WideString(Directory)),
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
for I:=0 to Files.Count-1 do
if FileExists(Files[I]) or DirectoryExists(Files[I]) then
begin
SetLength(FilePIDL, Length(FilePIDL)+1);
OleCheck(ShellParentFolder.ParseDisplayName(HND, nil,
PWideChar(WideString(SelVal(Directory='', Files[I], ExtractFileName(Files[I])))),
chEaten, FilePIDL[High(FilePIDL)], dwAttributes)); // Get the relative PItemIDList of the File
end;
ShellParentFolder.GetUIObjectOf(HND, Length(FilePIDL), FilePIDL[0], IID_IContextMenu, nil, CM); // get the IContextMenu Interace for the file
if CM<>nil then
begin
P.X:=X;
P.Y:=Y;
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;
HR:=CM.GetCommandString(ICmd, GCS_VERBA, nil, ZVerb, SizeOf(ZVerb));
Verb:=StrPas(ZVerb);
Handled:=False;
if Supports(nil, IShellCommandVerb, SCV) then
begin
HR:=0;
SCV.ExecuteCommand(Verb, Handled);
end;
if not Handled then
begin
FillChar(ICI, SizeOf(ICI), #0);
with ICI do
begin
cbSize:=SizeOf(ICI);
hWND:=0;
lpVerb:=MakeIntResourceA(ICmd);
nShow:=SW_SHOWNORMAL;
end;
HR:=CM.InvokeCommand(ICI);
result:=HR=S_OK;
end;
if Assigned(SCV) then
SCV.CommandCompleted(Verb, HR=S_OK);
end;
finally
DestroyMenu(Menu);
end;
end;
Finalize(FilePIDL);
end;