新的 TFileOpenDialog 和旧的 TOpenDialog 有啥区别?

Posted

技术标签:

【中文标题】新的 TFileOpenDialog 和旧的 TOpenDialog 有啥区别?【英文标题】:What is the difference between the new TFileOpenDialog and the old TOpenDialog?新的 TFileOpenDialog 和旧的 TOpenDialog 有什么区别? 【发布时间】:2011-09-08 08:10:10 【问题描述】:

新的 TFileOpenDialog 和旧的 TOpenDialog 有什么区别? 在我的电脑(Win 7/DXE)中,当我运行代码时,对话框看起来是一样的。

【问题讨论】:

TFileOpenDialog 实现了 Vista 风格的打开对话框,但在以前的 Windows 版本中回退到旧风格。 @GolezTrol,TFileOpenDialog 在 XP 下运行时引发异常。 @Uwe Raabe。无法测试,但我相信你是对的。我的错。 【参考方案1】: TOpenDialog 包装了传统的 GetOpenFileName。它适用于所有版本的 Windows。 TFileOpenDialog 封装了在 Vista 中引入的基于 COM 的新对话框。因此,它仅适用于 Vista 或更高版本。它具有比旧对话框更多的功能,尤其是与搜索的紧密集成。

Vista 常用对话框

兼容性常用对话框

如果调用正确,GetOpenFileName API 实际上会在大多数情况下生成新对话框,因此您实际上无法区分。也就是说,从历史上看,VCL 的 GetOpenFileName 包装器的实现并不精确,并且总是导致显示兼容性对话框。

但是新的 COM 对话框必须提供什么呢?

新对话框提供了更简单的自定义界面,但失去了一些通用性。如果您在 Vista 或更高版本上使用带有 GetOpenFileName 的旧对话框模板自定义,则对话框会降级为缺乏功能的丑陋兼容性版本。

新对话框的另一大优势是可以选择无限数量的文件。旧的GetOpenFileName 接口在固定大小的缓冲区中返回多选文件名。这可能是一个真正的限制,在我自己的代码中,当我的应用在 XP 上运行时,我不得不修改 VCL 代码以使这个缓冲区更大。

TOpenDialog 将尽可能将工作委托给TFileOpenDialog。它使用的测试要求满足以下所有条件:

在 Windows Vista 或更高版本上运行。 Dialogs.UseLatestCommonDialogs 全局布尔变量为真(默认为真)。如果您选择这样做,这允许您禁用新 COM 对话框的使用。 未指定对话框模板。 OnIncludeItemOnCloseOnShow 事件均未分配。大概这些不能被TFileOpenDialog 解雇。

总结

如果您继续使用TOpenDialog,那么您将在多选模式下获得无限数量的文件的好处。但是,如果您希望自定义对话框,并拥有新的对话框而不是丑陋的兼容性对话框,那么您需要执行以下操作:

在 XP 上使用 TOpenDialog 和对话框模板方法。 在 Vista 及更高版本上使用 TFileOpenDialog 并使用 IFileDialogCustomize 实现自定义。

【讨论】:

等一下,你和 Uwe 互相矛盾。我删除了 +1,但会在问题解决后立即恢复...我刚刚检查过,Uwe 是对的。 @Andreas 好的,我想它现在已经修复了。 如果我没记错的话,这不是 VCL 的不精确,而是不断变化的 OPENFILENAME 结构。 VCL 与早期的操作系统版本兼容,声明了较小的结构,从而导致显示较旧的对话框。不过我可能错了.. 在 Delphi XE2 中,还有一个条件:StyleServices.Enabled 必须为真。有人知道为什么吗???我用旧样式的Win 7,为什么禁用新对话框??? @oxo 这是 VCL 中的一个错误。有许多类似的错误。这就是我在系统文件对话框中使用自己的包装器的原因之一。任务对话框包装器也出现了同样的错误。 VCL 编码器不够好。【参考方案2】:

TOpenDialog在满足以下条件时执行TFileOpenDialog

    程序在 Vista(及更高版本)下运行 UseLatestCommonDialogs 为真(这是默认值) 没有设置OnIncludeItemOnCloseOnShow 事件

因此,在您的系统上仍然使用TOpenDialog 时,在大多数情况下,您可能最终会自动执行TFileOpenDialog,这就解释了为什么它们对您来说看起来一样。

备注:TFileOpenDialog 不会退回到旧的 Windows 系统(XP 及以下) - 它只会引发异常。相反,TOpenDialog 会做某种“前倾”。

【讨论】:

一些非常小的抱怨:1) 您错过了对应该出现在项目符号中的对话模板的任何引用。 2) GetOpenFileName 通常也会产生闪亮的新对话框,只要它以特定方式调用。我实际上不确定 VCL 的现代版本是否以适当的方式调用 GetOpenFileName,但现在 TFileOpenDialog 在幕后使用,这有点没有实际意义。 @David Heffernan,我实际上查看了 Template 属性,但由于它受到保护并且从未在标准对话框组件中设置,因此我决定在此处省略它。否则我将不得不解释如何使用它。 模板受保护?我没有意识到这一点,但我使用自己的包装器而不是 VCL 包装器。问题是对话框自定义是导致您使用 TFileOpenDialog 的主要问题。 因此,明智的做法是使用“旧”TOpenDialog 以获得与 XP 和 7 的兼容性。谢谢。 +1 并被接受。

以上是关于新的 TFileOpenDialog 和旧的 TOpenDialog 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

NXLog 和旧的 Windows 事件

scikitkearn 标签编码器和旧的分类编码器有啥区别?

将旧的时间字符串转换为新的string时间字符串

for 循环时 key的作用

二进制XCFramework是否可以和旧版swift一起使用?

实习第三天的感悟