Only saw examples at online to select one file in explorer, and thought maybe someone else can also benefit from version that selects multiple files. Or harden this one if needed,
-Tee-
function OpenFolderAndSelectFiles(const AFileNames: TStringList): Boolean;
procedure CheckFilesHaveSameRoot(const AFileNames: TStringList);
var
I: Integer;
LDirectory: string;
begin
LDirectory := ExtractFilePath(AFileNames[0]);
for I := 1 to AFileNames.Count - 1 do
if not SameText(LDirectory, ExtractFilePath(AFileNames[I])) then
raise EFileNotFoundException.CreateFmt('File "%s" is not in common root "%s"', [AFileNames[I], LDirectory]);
end;
var
LDirectory: string;
LPDirectoryItemID: PItemIDList;
I: Integer;
LFileArray: TArray<PItemIDList>;
LDidInitCOM: Boolean;
LAPIResult: HResult;
begin
CheckFilesHaveSameRoot(AFileNames);
Result := False;
LDidInitCOM := False;
LDirectory := ExtractFilePath(AFileNames[0]);
LPDirectoryItemID := ILCreateFromPath(PChar(LDirectory));
if Assigned(LPDirectoryItemID) then
try
SetLength(LFileArray, AFileNames.Count);
for I := 0 to AFileNames.Count - 1 do
LFileArray[I] := ILCreateFromPath(PChar(AFileNames[I]));
while True do
begin
LAPIResult := SHOpenFolderAndSelectItems(LPDirectoryItemID, AFileNames.Count, @LFileArray[0], 0);
if LAPIResult = CO_E_NOTINITIALIZED then
begin
LDidInitCOM := Succeeded(CoInitialize(nil));
if not LDidInitCOM then
raise Exception.Create('Could not initialize COM');
end
else
Break;
end;
Result := LAPIResult = S_OK;
finally
ILFree(LPDirectoryItemID);
for I := 1 to AFileNames.Count - 1 do
ILFree(LFileArray[I]);
if LDidInitCOM then
CoUninitialize;
end;
end;