Вот версия Delphi подхода, предоставленная Саймон Мурье:
uses
ComObj, ShellAPI, ShlObj, ActiveX, SHDocVw, ShLwApi;
function IUnknown_QueryService(punk: IUnknown; const guidService: TGUID;
const IID: TGUID; out Obj): HRESULT; stdcall; external 'ShLwApi'
name 'IUnknown_QueryService';
type
TFolderViewMode = (fvmAuto, fvmIcon, fvmSmallIcon, fvmList, fvmDetails,
fvmThumbnail, fvmTile, fvmThumbstrip, fvmContent);
procedure OpenFolder(AHandle: HWND; const AFolder: string; AViewMode: TFolderViewMode);
const
FolderViewModes: array[TFolderViewMode] of Cardinal =
(Cardinal(FVM_AUTO), FVM_ICON, FVM_SMALLICON, FVM_LIST, FVM_DETAILS,
FVM_THUMBNAIL, FVM_TILE, FVM_THUMBSTRIP, FVM_CONTENT);
var
ShellItem: IShellItem;
PIDL: PItemIDList;
SEInfo: TShellExecuteInfo;
ILSize: Cardinal;
SafeArray: PSafeArray;
v: OleVariant;
ShellWindows: IShellWindows;
ExplorerHWND: Integer;
disp: IDispatch;
view: IFolderView;
dummy: OleVariant;
begin
OleCheck(CoInitialize(nil));
try
OleCheck(SHCreateItemFromParsingName(PChar(AFolder), nil, IShellItem, ShellItem));
try
OleCheck((ShellItem as IPersistIDList).GetIDList(PIDL));
try
ZeroMemory(@SEInfo, SizeOf(SEInfo));
SEInfo.cbSize := SizeOf(SEInfo);
SEInfo.Wnd := AHandle;
SEInfo.fMask := SEE_MASK_IDLIST;
SEInfo.nShow := SW_SHOW;
SEInfo.lpIDList := PIDL;
Win32Check(ShellExecuteEx(@SEInfo));
ILSize := ILGetSize(PIDL);
SafeArray := SafeArrayCreateVector(VT_UI1, 0, ILSize);
CopyMemory(SafeArray.pvData, PIDL, ILSize);
PVariantArg(@v).vt := VT_ARRAY or VT_UI1;
PVariantArg(@v).parray := SafeArray;
OleCheck(CoCreateInstance(CLASS_ShellWindows, nil, CLSCTX_LOCAL_SERVER,
IShellWindows, ShellWindows));
try
dummy := Unassigned;
var c: Integer := 0;
repeat
if c > 0 then
Sleep(200);
disp := ShellWindows.FindWindowSW(v, dummy, SWC_BROWSER, ExplorerHWND,
SWFO_NEEDDISPATCH);
Inc(c);
until Assigned(disp) or (c > 15);
if disp = nil then
Exit;
OleCheck(IUnknown_QueryService(disp, IFolderView, IFolderView, view));
try
OleCheck(view.SetCurrentViewMode(FolderViewModes[AViewMode]));
finally
view := nil;
end;
finally
ShellWindows := nil;
end;
finally
CoTaskMemFree(PIDL);
end;
finally
ShellItem := nil;
end;
finally
CoUninitialize;
end;
end;
Вместо бесконечного опроса окна во сне (и потенциального уничтожения приложения!), я сдаюсь через 3 секунды.
Пример использования:
procedure TForm1.Button1Click(Sender: TObject);
begin
OpenFolder(Handle, 'C:\Users\Andreas Rejbrand\Skrivbord\Test', fvmThumbnail);
end;
Режимы просмотра,
type
TFolderViewMode = (fvmAuto, fvmIcon, fvmSmallIcon, fvmList, fvmDetails,
fvmThumbnail, fvmTile, fvmThumbstrip, fvmContent);
сопоставляются непосредственно с FOLDERVIEWMODE
s. Обратите внимание, что ваша версия Windows может не поддерживать их все.
person
Andreas Rejbrand
schedule
17.05.2021
IFolderView
и использовать егоIFolderView::SetCurrentViewMode
метод. - person Andreas Rejbrand   schedule 15.05.2021