用户可以通过单击相应的列标题在标准 Windows 打开对话框(在“详细信息”视图模式下)按名称、日期或大小手动对文件进行排序。如何在应用程序中以编程方式在打开对话框(Delphi 中的 TOpenDialog 类)中设置排序模式,以便对话框以首选排序打开?
4 回答
TFileOpenDialog (D2009) 在内部使用来自 Windows 的 IFileDialog 接口。该界面不提供任何设置文件排序的方法。但是它确实有 SetClientGuid 和 ClearClientData。这些由 TFileOpenDialog 通过其 ClientGUID 属性使用。为您的特定实例设置 ClientGuid 会指示窗口保持对话框的状态。然后,Windows 将记住上次打开的文件夹、文件的列出方式和排序方式。
因此,如果您只想通过记住他们在打开文件时设置对话框的最后方式来适应您的用户,您所要做的就是设置 FileOpenDialog 的 ClientGUID。
要获取 GUID,请在代码编辑器中按 Ctrl-Shift-G。只需记住在将其粘贴到 ClientGUID 属性时不要使用方括号。
GetOpenFileName() API 和 Vista IFileDialog 接口对此不提供支持。您可以破解此杂志文章中演示的对话框。请注意,这篇文章已经过时了。而且像这样的黑客很脆弱,他们很可能会停止在下一个版本的 Windows 上工作。
你可以使用像 DexExpress' TcxShellListView 这样的组件来创建自己的组件。它允许对文件进行排序。
在谷歌搜索主题后,我发现了一些“神奇数字”并得出了以下解决方案(TOpenDialog.OnFolderChange 事件处理程序):
procedure TDM.OpenDlgFolderChange(Sender: TObject);
const
FCIDM_SHVIEW_LARGEICON = $7029;
FCIDM_SHVIEW_SMALLICON = $702A;
FCIDM_SHVIEW_LIST = $702B;
FCIDM_SHVIEW_REPORT = $702C;
FCIDM_SHVIEW_THUMBNAIL = $702D;
FCIDM_SHVIEW_TILE = $702E;
ByName = $7602;
BySize = $7603;
ByType = $7604;
ByModified = $7605;
ByAttributes = $7608;
var
Handle: THandle;
begin
Handle:= FindWindowEx(GetParent(OpenDlg.Handle), 0, 'SHELLDLL_DefView', nil);
SendMessage(Handle, WM_COMMAND, FCIDM_SHVIEW_REPORT, 0);
SendMessage(Handle, WM_COMMAND, ByAttributes, 0);
SendMessage(Handle, WM_COMMAND, ByName, 0);
end;
第一条消息设置“详细信息”查看模式,第二条设置排序“按属性”,第三条设置“按名称”;这两个不同的“排序”消息需要两个保证最终排序是升序的。
上述代码在 Win XP 上运行良好,但排序部分在 Win 2000 SP4 上不起作用;在 Win 7 上,“排序幻数”发生了变化,即“ByName = $7603”等。