我想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标志是解决方案的一部分).
你肯定不想测试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模式.使您的应用程序支持兼容模式不是您的职责.