属性 "ofOverwritePrompt" 在 Delphi 10.1 Berlin 中使用 VCL 样式时,TSaveDialog 不起作用

Property "ofOverwritePrompt" for TSaveDialog does not work when VCL Styles are used in Delphi 10.1 Berlin

  1. 创建新的 VCL Forms 应用程序
  2. 在主窗体上添加一个 Tbutton 和一个 TSaveDialog

  3. 在 SaveDialog1

  4. 的属性中将 "ofOverwritePrompt" 设置为 True
  5. 使用:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      SaveDialog1.Execute();
    end;
    
  6. 运行 应用程序。按下按钮执行保存对话框。尝试保存到一个已经存在的文件。 如果要替换文件,将出现一个消息框。按取消。到目前为止一切都很好。关闭应用程序。

  7. 转到 Project/Options/Application/Appearance 和 select 自定义样式(例如 Amakrits)。将 Amakrits 设置为默认样式。

  8. 运行 上面#5 中的应用程序。只会显示一小部分消息框。您必须按 Enter 键才能继续。

(使用 TFileSaveDialog 会得到相同的结果)

如果我使用 Delphi XE8 编译和 运行 应用程序,它会没问题,因为保存对话框 window 似乎使用默认的 windows 样式,即使另一个样式已选择。

编辑: 我有 Windows 10 pro。使用 Delphi 10.1 Berlin 编译为 win32 的源代码。 替换消息框被部分隐藏。只显示了左上角的一小部分,见图

这里是用XE8 win32编译的:

Ps。我使用默认的 100% 比例因子。

用 win64 (Delphi 10.1 Berlin) 编译似乎没问题:

因此,编译为 win32 对我不起作用,但 64 位可以。有什么线索吗?

编辑:尝试使用 "GetSaveFileName(OFN)" 在 win32 中对我也不起作用(win 64 没问题):

我无法确认问题,这里看起来一切正常(32 位可执行文件,以 Amakrits 为主题,使用 10.1 Berlin 编译,在 Windows 7 上,100% 缩放)但你可以试试这个:

uses ... Winapi.CommDlg;

...

var
  OFN: TOpenFileName;
begin
  FillChar(OFN, SizeOf(OFN), 0);
  OFN.lStructSize := SizeOf(OFN);
  OFN.nMaxFile := MAX_PATH;
  OFN.Flags := OFN_OVERWRITEPROMPT or OFN_HIDEREADONLY or OFN_ENABLESIZING or OFN_EXPLORER;
  GetSaveFileName(OFN);
end;

结果是一个以 Amakrits 为主题的新的类似资源管理器的保存对话框,(对我来说)效果很好。只有对话框左上角的两个圆形蓝色“后退”和“前进”(<-->)按钮看起来有点奇怪。

但我没有尝试使用自定义缩放设置(例如控制面板 -> 显示面板中的中等 125% 等)。我认为这可能会影响这些事情。

更新

我刚刚尝试使用 SaveDialog1(注释掉上面的 OFN 代码)和自定义显示缩放 (125%)。一切看起来都很好,所以不是这样。此外,当我使用 OFN 代码时,一切看起来都很好(实际上,更好,即没有 XP 风格的对话框,而是一个真正的类似资源管理器的对话框)。

如果我在 Project/Options/Application 中将 "Enable High-DPI" 设置为 true 它将起作用(替换框正确显示)。禁用它会导致问题(在 win32 和 win64 中)。

您可以使用 VCL Styles Utils 项目的对话框样式代码避免此问题。

只需将这些单元添加到您的项目中即可。

uses
  Vcl.Styles.Utils.Menus, //Popup and Shell Menus (class #32768)
  Vcl.Styles.Utils.Forms, //dialogs box (class #32770)
  Vcl.Styles.Utils.StdCtrls, //buttons, static, and so on
  Vcl.Styles.Utils.ComCtrls, //SysTreeView32, SysListView32
  Vcl.Styles.Utils.ScreenTips, //tooltips_class32 class
  Vcl.Styles.Utils.SysControls,
  Vcl.Styles.Utils.SysStyleHook;

{$R *.dfm}

procedure TForm26.Button1Click(Sender: TObject);
begin
  UseLatestCommonDialogs := false;
  SaveDialog1.Execute();
end;

郑重声明,我遇到了完全相同的问题(Delphi 10.1 Berlin,在 Windows 10 64 位,100% 屏幕设置,针对 32 位目标编译)。启用或禁用 High-DPMI 感知没有帮助。

解决方法是在执行 TSaveDialog(或 TOpenDialog)之前禁用对话框的样式,如下所示:

  TStyleManager.SystemHooks := TStyleManager.SystemHooks - [shDialogs];

文件对话框本身仍然是主题化的。如果弹出覆盖提示(或创建提示),您将获得标准 Windows 样式的消息框,但它们将足够大以供用户阅读和单击它们。文件对话框完成后,如果需要,您可以通过将 shDialogs 重新添加到 SystemHooks 来再次启用样式对话框。