在Windows10中的Delphi10.4.2Win-32VCL应用程序中,我使用以下代码并传递路径(例如C:\MyDirectory\
),在Windows File Explorer中显示了目录的内容
procedure ShellOpen(const Url: string; const Params: string = '');
begin
Winapi.ShellAPI.ShellExecute(0, 'Open', PChar(Url), PChar(Params), nil, SW_SHOWNORMAL);
end;
这是可行的。但是,如何使用缩略图强制资源管理器显示此目录中的文件?这个过程中有没有什么参数可以用到呢?
我已经为此搜索了很多次,但没有找到任何东西。
发布于 2021-05-16 17:31:03
您希望使用IFolderView::SetCurrentViewMode方法。
下面是一个C++ (使用Visual Studio的ATL)示例:
int main()
{
CoInitialize(NULL);
{
// get a shell item
CComPtr<IShellItem> folder;
ATLASSERT(SUCCEEDED(SHCreateItemFromParsingName(L"c:\\myPath1\myPath2", nullptr, IID_PPV_ARGS(&folder))));
// get its PIDL
CComHeapPtr<ITEMIDLIST> pidl;
ATLASSERT(SUCCEEDED(CComQIPtr<IPersistIDList>(folder)->GetIDList(&pidl)));
// open the item
SHELLEXECUTEINFO info = { };
info.cbSize = sizeof(info);
info.fMask = SEE_MASK_IDLIST;
info.nShow = SW_SHOW;
info.lpIDList = pidl;
ATLASSERT(ShellExecuteEx(&info));
// build a variant from the PIDL
UINT size = ILGetSize(pidl);
SAFEARRAY* psa = SafeArrayCreateVector(VT_UI1, 0, size);
CopyMemory(psa->pvData, pidl, size);
CComVariant v;
v.parray = psa;
v.vt = VT_ARRAY | VT_UI1;
// find the opened window
CComPtr<IShellWindows> windows;
ATLASSERT(SUCCEEDED(windows.CoCreateInstance(CLSID_ShellWindows)));
CComVariant empty;
long hwnd;
CComPtr<IDispatch> disp;
do
{
windows->FindWindowSW(&v, &empty, SWC_BROWSER, &hwnd, SWFO_NEEDDISPATCH, &disp);
if (disp)
break;
// we sleep for a while but using events would be better
// see https://stackoverflow.com/a/59974072/403671
Sleep(500);
} while (true);
// get IFolderView
CComPtr<IFolderView> view;
ATLASSERT(SUCCEEDED(IUnknown_QueryService(disp, IID_IFolderView, IID_PPV_ARGS(&view))));
// change view mode
ATLASSERT(SUCCEEDED(view->SetCurrentViewMode(FOLDERVIEWMODE::FVM_THUMBNAIL)));
}
CoUninitialize();
return 0;
}
发布于 2021-05-16 07:50:28
不,EXPLORER.EXE没有这个- it neither had one in , nor does it have one in 的参数。令人惊讶的是,无论如何,可用的参数很少。
最好的办法是先通过CreateProcessW()
启动浏览器,然后再启动obtain the handle of its main thread and finally find the new window。然后,您可以操作单个控件,如文件列表。参见基于AutoIt: Automating Windows Explorer的this answer -它主要使用IShellBrowser
和(超越Windows XP) IFolderView2.SetViewModeAndIconSize()
来应用FVM_THUMBNAIL
。
发布于 2021-05-18 02:04:23
这是Simon Mourier提供的approach的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);
直接映射到Windows的FOLDERVIEWMODE
s。请注意,您的Windows版本可能不支持所有这些功能。
https://stackoverflow.com/questions/67549234
复制相似问题