当前位置:  开发笔记 > 开发工具 > 正文

TSaveDialog失败,客户端视觉样式被禁用

如何解决《TSaveDialog失败,客户端视觉样式被禁用》经验,为你挑选了1个好方法。

我想TSaveDialog在Delphi XE6中使用a :

if not SaveDialog1.Execute(0) then
   Exit;

该调用立即返回false,而不显示任何对话框.我将其追溯到创建shell Save Dialog COM对象的行为:

function TCustomFileSaveDialog.CreateFileDialog: IFileDialog;
var
       LGuid: TGUID;
begin
  LGuid := CLSID_FileSaveDialog;

  CoCreateInstance(LGuid, nil, CLSCTX_INPROC_SERVER,
    StringToGUID(SID_IFileSaveDialog), Result);
end;

呼叫CoCreateInstance失败了.我创建了最少的代码来重现问题:

procedure TForm1.Button1Click(Sender: TObject);
const
   CLSID_FileSaveDialog: TGUID = '{C0B4E2F3-BA21-4773-8DBA-335EC946EB8B}';
begin
   CreateComObject(CLSID_FileSaveDialog);
end;

它抛出EOleSysError异常:

0x80040111:ClassFactory无法提供请求的类,ClassID:{C0B4E2F3-BA21-4773-8DBA-335EC946EB8B}

我的应用程序使用公共控件库(6.0.7601.18837)的第6版,但我意识到,如果用户已禁用我的应用程序的视觉样式时才会发生:

在此输入图像描述

我们仍在使用公共控件库的第6版,只IsAppThemed返回false.

注意:我知道很多人错误地认为:

Visual Styles API仅在我们加载了Comctrl32.dll版本6时才有效

如果加载了Comctrl32.dll的版本6,则Visual Styles API将起作用

如果我们不使用ComCtrl v6那么这意味着视觉样式被禁用

如果我们使用旧的公共控件库,则禁用视觉样式

蛮力解决方案是将全局UseLatestCommonDialogs设置为false.

但这非常糟糕,因为它仅适用于在应用程序中禁用视觉样式的人:

对话框继续在没有视觉样式的操作系统上工作(例如Windows Server 2008 R2)

关闭视觉样式后对话框继续工作(例如关闭视觉样式的Windows 7)

这意味着我不能简单地使用IsAppThemed,因为如果IsThemeActive为false 则返回false.

| IsThemeActive | IsAppThemed | Disable visual styles | Result    |
|---------------|-------------|-----------------------|-----------|
| True          | True        | Unchecked             | Works     |
| True          | False       | Checked               | Fails     |
| False         | False       | Unchecked             | Works     |
| False         | False       | Checked               | Fails     |

我想我要问的是如何检查Disble Visual Styles compat标志的状态.

我真正想问的是如何TSaveDialog在Delphi中正确地工作(并不意味着读取compat标志是解决方案的一部分).



1> David Heffer..:

你肯定不想测试compat标志.如果要进行测试,则需要测试该标志控制的内容.在这种情况下,是否使用主题.如果您要进行类似测试,则在满足以下条件时应使用Vista样式对话框:

IsWindowsVistaOrGreater and Winapi.UxTheme.InitThemeLibrary and Winapi.UxTheme.UseThemes

否则,您需要使用旧的XP样式对话框.您可以使用以下代码实现此目的:

UseLatestCommonDialogs := IsWindowsVistaOrGreater and Winapi.UxTheme.InitThemeLibrary 
  and Winapi.UxTheme.UseThemes;

但问题是,当用户使用Windows经典主题运行时,您将禁用新样式对话框.我确信你不想要.

所以你可以采用基于功能的方法.如果新的失败,那就是尝试在旧样式对话框中使用新样式对话框和回退.所以,尝试创建一个IFileSaveDialog.UseLatestCommonDialogs根据是否成功进行分配.


另一方面,此compat设置旨在用于启用主题时无法正常工作的应用程序.您的应用程序在主题下可以正常工作,我认为您的应用程序不支持该特定的compat模式是完全合理的.

您不应该支持兼容模式.例如,如果你停止支持XP,那么你不会期望支持XP compat垫片.

经过反思,这是我对你的建议.什么都不做.如果您的用户以这种方式询问您的应用是否失败,请告诉他们您不支持该compat模式.使您的应用程序支持兼容模式不是您的职责.

推荐阅读
手机用户2402852307
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有