当用户打开使用资源管理器搜索找到的文件而启动程序时,有没有办法实现有用的"打开文件夹中的下一个/上一个文件"功能?
例如,应用程序与 *.jpg 相关联。用户在资源管理器中搜索 foo*.jpg 并打开 foobar1.jpg。应用程序将启动。当用户使用应用程序的"文件夹中的下一个文件"命令时,应用程序将打开搜索返回的下一个文件,而不是与 foobar1.jpg 位于同一文件夹中的下一个文件。
这可能吗?
当用户在 Windows 资源管理器中打开文件时,shell 会枚举所有可用的上下文菜单命令并运行第一个默认命令。因此,只需创建新的上下文菜单外壳扩展并将其注册到文件扩展名ProgID上即可。您的 shell 扩展必须实现 3 个接口:IObjectWithSite、IShellExtInit 和 IContextMenu。不要忘记创建 MayChangeDefaultMenu reg 子项。
您的上下文菜单可以从任何程序使用。如果调用方调用IObjectWithSite.SetSite,则表示文件已在Windows资源管理器中打开。如果未调用IObjectWithSite.SetSite - 则文件已从任何其他应用程序打开。
当shell调用IShellExtInit时,从传递的IDataObject中提取文件名并存储它们。当 shell 调用 IContextMenu.QueryContextMenu 时,将命令添加到带有MFS_DEFAULT标志的菜单中。当 shell 调用 IContextMenu.GetCommandString(GCS_VERB) 时,您必须返回"open"字符串。当shell调用IContextMenu.InvokeCommand时,运行您的应用程序并在参数中传递文件名和CMINVOKECOMMANDINFO.hwnd。
在您的应用程序内部分析参数,如果找到 hwnd,则意味着您必须从 hwnd 获取文件列表。
查找资源管理器实例:
OleCheck(CoCreateInstance(CLASS_ShellWindows, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IShellWindows, ShellWindows));
for i := ShellWindows.Count - 1 downto 0 do
begin
Dispatch := ShellWindows.Item(i);
Dispatch.QueryInterface(IServiceProvider, ServiceProvider);
ServiceProvider.QueryService(SID_STopLevelBrowser, IShellBrowser, ShellBrowser);
ShellBrowser.GetWindow(Hwnd);
if Hwnd = HwndFromParams then InstanceFound;
end;
创建文件列表:
ShellBrowser.QueryActiveShellView(ShellView);
ShellView.QueryInterface(IFolderView, FolderView);
FolderView.Items(SVGIO_ALLVIEW)
现在,您已经拥有了 Windows 资源管理器实例中的所有文件,您可以在导航中使用它们。