【问题标题】:How to change path of an existing Windows Explorer window?如何更改现有 Windows 资源管理器窗口的路径?
【发布时间】:2012-07-06 09:45:17
【问题描述】:

我有一个打开的 Windows 资源管理器窗口的句柄。

如何向它发送命令以将路径从
示例:m:\programs 更改为 d:\programs


到目前为止,我一直在使用ShellExecute(),但它会打开一个新窗口。这不好(用户体验)。

【问题讨论】:

  • 你有一个 HWND 给 explorer 吗?你不是要为此使用 IShellBrowser 和 IShellView 吗?
  • @DavidHeffernan,我会在谷歌上搜索一些信息以供您推荐。谢谢。
  • @Kabamaru:不需要谷歌,因为你知道你正在走向 MSDN:IShellBrowserIShellView
  • @AndreasRejbrand , DavidHeffernan,你能举个例子吗?
  • 为什么尊重用户关于是否重用windows的配置不是一个好的UX?

标签: delphi winapi windows-shell


【解决方案1】:

以下BrowseToFolder 函数将给定AHandle 句柄(如果存在)的Windows 资源管理器的现有实例导航到AFolderPath 文件夹(如果存在)。如果您不指定第二个参数,则应采用最顶部的窗口进行导航(或者至少文档声称;现实似乎采用最旧的现有窗口)。如果导航成功,函数返回True,否则返回False:

uses
  ActiveX, ShlObj, ShellAPI, SHDocVw;

const
  IID_IServiceProvider: TGUID = '{6D5140C1-7436-11CE-8034-00AA006009FA}';
  SID_STopLevelBrowser: TGUID = '{4C96BE40-915C-11CF-99D3-00AA004AE837}';

function GetItemIDListFromPath(const AFolderPath: WideString): PItemIDList;
var
  Count: ULONG;
  Attributes: ULONG;
  ShellFolder: IShellFolder;
begin
  Result := nil;
  if Succeeded(SHGetDesktopFolder(ShellFolder)) then
  begin
    Count := 0;
    if Failed(ShellFolder.ParseDisplayName(0, nil, PWideChar(AFolderPath),
      Count, Result, Attributes))
    then
      Result := nil;
  end;
end;

function BrowseToFolder(const AFolderPath: WideString;
  AHandle: HWND = HWND_TOPMOST): Boolean;
var
  I: Integer;
  WndIface: IDispatch;
  ItemIDList: PItemIDList;
  ShellBrowser: IShellBrowser;
  ShellWindows: IShellWindows;
  WebBrowserApp: IWebBrowserApp;
  ServiceProvider: IServiceProvider;
begin
  Result := False;

  if Succeeded(CoCreateInstance(CLASS_ShellWindows, nil, CLSCTX_LOCAL_SERVER,
    IID_IShellWindows, ShellWindows)) then
  begin
    for I := 0 to ShellWindows.Count - 1 do
    begin
      if (AHandle <> HWND_TOPMOST) then
        WndIface := ShellWindows.Item(VarAsType(I, VT_I4))
      else
        WndIface := ShellWindows.Item(VarAsType(SWC_EXPLORER, VT_UI4));

      if Succeeded(WndIface.QueryInterface(IID_IWebBrowserApp,
        WebBrowserApp)) then
      begin
        if (AHandle = HWND_TOPMOST) or (WebBrowserApp.HWnd = AHandle) then
        begin
          if Succeeded(WebBrowserApp.QueryInterface(IID_IServiceProvider,
            ServiceProvider)) then
          begin
            if Succeeded(ServiceProvider.QueryService(SID_STopLevelBrowser,
              IID_IShellBrowser, ShellBrowser)) then
            begin
              ItemIDList := GetItemIDListFromPath(AFolderPath);
              Result := Succeeded(ShellBrowser.BrowseObject(ItemIDList,
                SBSP_SAMEBROWSER or SBSP_ABSOLUTE));
            end;
          end;
          Break;
        end;
      end;
    end;
  end;
end;

以下是示例用法:

procedure TForm1.Button1Click(Sender: TObject);
var
  ExplorerHandle: HWND;
begin
  ExplorerHandle := 123456;

  if not BrowseToFolder('c:\Windows\System32\', ExplorerHandle) then
    ShowMessage('Navigation to a folder failed!')
  else
    ShowMessage('Navigation to a folder succeeded!');
end;

这是我从中获得灵感的complete testing projectthe blog post

【讨论】:

  • 谢谢@TLama。很好的答案
  • 很高兴我能帮上忙(虽然延迟很大:-)
猜你喜欢
  • 1970-01-01
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-14
  • 2018-06-17
  • 1970-01-01
相关资源
最近更新 更多