Einzelnen Beitrag anzeigen

tomkupitz

Registriert seit: 26. Jan 2011
339 Beiträge
 
Delphi 12 Athens
 
#1

"Explorer Kontext Menü"

  Alt 18. Apr 2020, 23:54
Hallo,

ich habe hier ein Beispiel für ein "Explorer Kontext Menü" gefunden. Funktioniert auch soweit, ausser wenn z.B. Directory:='C:\' und Files[0]:='C:\' sind. Gibt es dafür eine Lösung?

Code:
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;
  Mit Zitat antworten Zitat