我正在尝试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}
我的应用程序使用的是 Common Controls 库的第 6 版(6.0.7601.18837),但我意识到只有当用户为我的应用程序禁用视觉样式时才会发生这种情况:
我们仍在使用公共控件库的版本 6,只是IsAppThemed
返回 false。
注意:我知道很多人错误地认为:
- Visual Styles API 仅在我们加载了版本 6 的 Comctrl32.dll 时才有效
- 如果加载了 Comctrl32.dll 版本 6,则 Visual Styles API 将起作用
- 如果我们没有使用 ComCtrl v6,那么这意味着视觉样式被禁用
- 如果我们使用旧的通用控件库,视觉样式将被禁用
蛮力解决方案是将全局UseLatestCommonDialogs设置为 false。
但这很糟糕,因为它只适用于在他们的应用程序中禁用了视觉样式的人:
- 该对话框继续在没有视觉样式的操作系统上工作(例如 Windows Server 2008 R2)
- 对话框在关闭视觉样式的情况下继续工作(例如,关闭视觉样式的 Windows 7)
这意味着我不能简单地使用IsAppThemed
,因为如果IsThemeActive
为假,它也会返回假。
| 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兼容标志的状态。
我真正要问的是如何TSaveDialog
在 Delphi 中正确地工作(并不暗示读取 compat 标志是解决方案的一部分)。