ikathegreat
ikathegreat

Reputation: 2321

Open Windows Explorer directory, select a specific file (in Delphi)

I have a procedure to open a folder in Windows Explorer that gets passed a directory path:

procedure TfrmAbout.ShowFolder(strFolder: string);
begin
   ShellExecute(Application.Handle,PChar('explore'),PChar(strFolder),nil,nil,SW_SHOWNORMAL);
end;

Is there a way to also pass this a file name (either the full file name path or just the name + extension) and have the folder open in Windows Explorer but also be highlighted/selected? The location I am going to has many files and I need to then manipulate that file in Windows.

Upvotes: 21

Views: 31173

Answers (2)

Coogara
Coogara

Reputation: 21

The answers at delphi.lonzu.net and swissdelphicenter offer a simpler solution to this. I've only tested it on Windows 10, 1909,, but the gist of it is:

uses ShellApi, ...
...
var
   FileName : TFileName;
begin
  FileName := 'c:\temp\somefile.html';

  ShellExecute(Handle, 'OPEN', 
    pchar('explorer.exe'), 
    pchar('/select, "' + FileName + '"'), 
    nil, 
    SW_NORMAL);
end;

This is simple and easy to use. Whether it works with older versions of Windows, I don't know.

Upvotes: 2

Andreas Rejbrand
Andreas Rejbrand

Reputation: 108948

Yes, you can use the /select flag when you call explorer.exe:

ShellExecute(0, nil, 'explorer.exe', '/select,C:\WINDOWS\explorer.exe', nil,
  SW_SHOWNORMAL)

A somewhat more fancy (and perhaps also more reliable) approach (uses ShellAPI, ShlObj):

const
  OFASI_EDIT = $0001;
  OFASI_OPENDESKTOP = $0002;

{$IFDEF UNICODE}
function ILCreateFromPath(pszPath: PChar): PItemIDList stdcall; external shell32
  name 'ILCreateFromPathW';
{$ELSE}
function ILCreateFromPath(pszPath: PChar): PItemIDList stdcall; external shell32
  name 'ILCreateFromPathA';
{$ENDIF}
procedure ILFree(pidl: PItemIDList) stdcall; external shell32;
function SHOpenFolderAndSelectItems(pidlFolder: PItemIDList; cidl: Cardinal;
  apidl: pointer; dwFlags: DWORD): HRESULT; stdcall; external shell32;

function OpenFolderAndSelectFile(const FileName: string): boolean;
var
  IIDL: PItemIDList;
begin
  result := false;
  IIDL := ILCreateFromPath(PChar(FileName));
  if IIDL <> nil then
    try
      result := SHOpenFolderAndSelectItems(IIDL, 0, nil, 0) = S_OK;
    finally
      ILFree(IIDL);
    end;
end;

Upvotes: 55

Related Questions