-1

我有一个使用 C++ Builder 2009 构建的旧应用程序,很长一段时间都没有受到影响,它仍然可以正常工作。也就是说.. 今天我注意到一些TSaveDialog->Options在我的 Windows 10 系统上无法正常工作。为了确保我不是在做梦,我在较旧的 Windows 版本(我尝试过 XP)上测试了相同的应用程序,并且它按预期工作得非常好。

TSaveDialog实例是在设计时设置的Options[ofHideReadOnly,ofAllowMultiSelect,ofEnableSizing]

我今天注意到(在 Windows 10 上)ofAllowMultiSelect不再起作用了?而是ofOverwritePrompt(错误地)使用!换句话说,我不能再选择两个或更多文件,当我选择一个已经存在的文件时,我首先会看到一个“确认另存为”对话框。

当我在我的 Windows 10 系统上使用 C++ Builder 2009 以调试模式和检查再次编译时,调试Options器似乎(仍然)正确地看到ofHideReadOnly, ofAllowMultiSelect, ofEnableSizing,但问题仍然存在。所以这不是好像价值观以某种方式改变了?

当我在运行时尝试时:

SaveDialog->Options.Clear() ;
SaveDialog->Options << ofHideReadOnly << ofEnableSizing << ofAllowMultiSelect ;

问题也依然存在!

当我删除ofAllowMultiSelect(在运行时或设计时)时,现有文件上不再显示“确认另存为”(但我显然仍然无法选择多个文件)。

老实说,我对此感到震惊?不知道下一步该怎么做 ?我没有选择测试更新的 c++ 版本,但我也很难理解编译器如何在这里负责。

任何指导表示赞赏。
由于 C++ Builder 和 Delphi 之间的 VCL 重叠而添加了 Delphi 标记

4

1 回答 1

1

在 Windows Vista 及更高版本上,如果且仅当满足所有这些条件时:

  • 全局Dialogs::UseLatestCommonDialogs变量是true
  • 并且TSaveDialog::Template财产是NULL
  • 并且TSaveDialog::OnIncludeItem,TSaveDialog::OnCloseTSaveDialog::OnShow事件没有分配处理程序

然后TSaveDialog将在内部使用 Win32IFileSaveDialog界面,其中ofAllowMultiSelect选项将映射到该对话框的FOS_ALLOWMULTISELECT选项,根据文档,仅由不支持IFileSaveDialog,仅由支持:IFileOpenDialog

FOS_ALLOWMULTISELECT
使用户能够在打开的对话框中选择多个项目。请注意,设置此标志时,IFileOpenDialog必须使用接口来检索这些项目。

如果不满足上述 3 个条件,则将TSaveDialog在内部使用 Win32GetSaveFileName()函数,其中ofAllowMultiSelect选项将映射到该对话框的OFN_ALLOWMULTISELECT选项,由1支持GetSaveFileName()

这就是为什么您在 Windows XP 和 Windows 10 上运行应用程序时会看到行为差异的原因。

因此,如果您希望TSaveDialog在较新的 Windows 版本上保持旧行为,则需要确保这 3 个条件中的至少 1 个不满足。例如,通过UseLatestCommonDialogs=false在调用之前设置SaveDialog->Execute(),或通过将(空)事件处理程序分配给OnIncludeItem//事件之一OnCloseOnShow

或者,您可以直接调用GetSaveFileName(),而不是使用TSaveDialog

1:但是,请注意,在 Vista+ 上,GetSaveFileName()它只是 的包装器IFileSaveDialog,仅用于向后兼容。因此,即使您确实在 Windows 10 上使用过,您仍然可能无法获得所需的确切行为。GetSaveFileName()


附带说明:此代码不像您认为的那样工作:

SaveDialog->Options.Clear();
SaveDialog->Options << ofHideReadOnly << ofEnableSizing << ofAllowMultiSelect;

Options属性实际上没有更新!在这两个语句中,从 读取Options属性,返回一个临时的,然后您正在修改它,但不分配回属性。IOW,代码有效地执行以下操作:TOpenOptionsOptions

TOpenOptions temp1 = SaveDialog->Options;
temp1.Clear();

TOpenOptions temp2 = SaveDialog->Options;
temp2 << ofHideReadOnly << ofEnableSizing << ofAllowMultiSelect;

因此,要Options正确更新属性,请改用:

SaveDialog->Options = TOpenOptions() << ofHideReadOnly << ofEnableSizing << ofAllowMultiSelect;
于 2021-09-04T02:39:28.683 回答