Я пытаюсь использовать в Delphi XE6 в TSaveDialog
:TSaveDialog терпит неудачу с клиентами визуальных стилей отключенными
if not SaveDialog1.Execute(0) then
Exit;
вызов немедленно возвращает ложные, без отображения диалогового окна. Я проследил его до акта создания оболочки Диалог сохранения 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 общей библиотеки Controls (6.0.7601.18837), но я понял, что это только Happe нс, если пользователь отключил визуальные стили для моего приложения:
Мы до сих пор используют версию 6 из общей библиотеки элементов управления, так что IsAppThemed
возвращает ложь.
Примечание: Я знаю, что многие люди ошибочно полагают, что:
- Visual Styles API работает только если у нас есть версия 6 из Comctrl32.dll загруженную
- Если версия 6 из Comctrl32. dll будет загружен, тогда API визуальных стилей будет работать
- Если мы не используем ComCtrl v6, значит, визуальные стили отключены
- Визуальные стили отключены, если мы используем старый общий контроль библиотека
Решение перебором является создание глобальной UseLatestCommonDialogs к ложным.
Но это очень плохо, так как это относится только к людям, которые имеют инвалидов визуальные стили в их применении:
- диалог продолжает работать на ОС без визуальных стилей (например, 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 Compat флаг.
Что я действительно спрашиваю, как правильно сделать работу TSaveDialog
в Delphi (не подразумевая, что чтение флага совместимости является частью решения).
Надеюсь, это не слишком тупой запрос, но почему «SaveDialog1.Execute (0)», а не более обычный «SaveDialog1.Execute»? – MartynA
@MartynA Ну, есть три причины для этого: i) '.Execute' не отображается в представлении кода ii) Вызов' .Execute' заставляет окно принадлежать 'ApplicationMainHandle' iii) На самом деле я хочу, чтобы диалог был (например, 'SaveDialog1.Execute (Self.Handle)'). Но я не хотел, чтобы люди фокусировались на параметре, переданном 'Execute', поэтому я упростил его для' .Execute (0) '. На самом деле, владельцы окон Delphi сломаны, и он игнорировал владельца - вместо этого он делал все, что захочет. –
с учетом этого принятого ответа: http://superuser.com/questions/694734/what-does-compatibility-option-disable-visual-themes-do разумно проверить ['IsCompositionActive'] (https: // msdn.microsoft.com/en-us/library/windows/desktop/bb759811(v=vs.85).aspx) также? Просто гадать – fantaghirocco