Próbuję użyć TSaveDialog
w Delphi XE6:TSaveDialog nie z klientem wizualnych stylów wyłączone
if not SaveDialog1.Execute(0) then
Exit;
Wezwanie natychmiast powraca fałszywy, bez wyświetlania okna dialogowego. I prześledzić go do aktu tworzenia powłoki obiektu Zapisz Dialog COM:
function TCustomFileSaveDialog.CreateFileDialog: IFileDialog;
var
LGuid: TGUID;
begin
LGuid := CLSID_FileSaveDialog;
CoCreateInstance(LGuid, nil, CLSCTX_INPROC_SERVER,
StringToGUID(SID_IFileSaveDialog), Result);
end;
Wezwanie do CoCreateInstance
zawodzi. Stworzyłem minimalny kod do odtworzenia problemu:
procedure TForm1.Button1Click(Sender: TObject);
const
CLSID_FileSaveDialog: TGUID = '{C0B4E2F3-BA21-4773-8DBA-335EC946EB8B}';
begin
CreateComObject(CLSID_FileSaveDialog);
end;
To rzuca EOleSysError wyjątek:
0x80040111: ClassFactory nie może dostarczyć żądanej klasy, CLASSID: {C0B4E2F3-BA21-4773-8DBA-335EC946EB8B }
Moja aplikacja jest używając wersji 6 wspólnej biblioteki kontrolnej (6.0.7601.18837), ale uświadomiłem sobie, że tylko Happe ns, jeśli użytkownik wyłączył style wizualne dla mojej aplikacji:
Ciągle używając wersji 6 wspólnej biblioteki Controls, tylko że IsAppThemed
zwraca false.
Uwaga: Znam wiele osób błędnie uważa, że:
- Style wizualne API działa tylko wtedy, gdy mamy Wersja 6 Comctrl32.dll załadowany
- Jeśli wersja 6 Comctrl32. dll jest ładowany, a następnie Visual Styles API zadziała
- Jeśli nie używamy ComCtrl v6, oznacza to, że Style wizualne są wyłączone
- Style wizualne są wyłączone, jeśli używamy stary wspólna biblioteka kontrole
Rozwiązanie brute-force jest stworzenie globalnego UseLatestCommonDialogs false.
Ale to jest bardzo złe, ponieważ odnosi się tylko do ludzi, którzy mają niepełnosprawne stylów wizualnych we wniosku:
- okno kontynuuje prace nad OS bez stylów wizualnych (np Windows Server 2008 R2)
- okno kontynuuje współpracę z style wizualne wyłączony (np Windows 7 z style wizualne wyłączony)
oznacza to, że nie można po prostu użyć IsAppThemed
, jak również zwraca wartość false, jeśli IsThemeActive
jest fałszywe.
| IsThemeActive | IsAppThemed | Disable visual styles | Result |
|---------------|-------------|-----------------------|-----------|
| True | True | Unchecked | Works |
| True | False | Checked | Fails |
| False | False | Unchecked | Works |
| False | False | Checked | Fails |
Co Chyba jestem pytaniem jest, jak sprawdzić stan Disble style wizualne compat flagi.
Naprawdę pytam, jak sprawić, aby TSaveDialog
działał poprawnie w Delphi (bez sugerowania, że czytanie flagi compat jest częścią rozwiązania).
Mam nadzieję, że to nie jest zbyt rozwlekłe zapytanie, ale dlaczego "SaveDialog1.Execute (0)", a nie bardziej "SaveDialog1.Execute"? – MartynA
@MartynA Cóż, istnieją trzy powody, dla których i) '.Execute' nie pojawia się wglądu w kod ii) Wywołanie' .Execute' powoduje, że okno jest własnością 'ApplicationMainHandle' iii) W rzeczywistości chcę, aby okno dialogowe było własnością formularza, na który patrzę (np. 'SaveDialog1.Execute (Self.Handle)'). Ale nie chciałem, aby ludzie koncentrowali się na parametrze przekazanym do 'Execute', więc uprościłem go do' .Execute (0) '. W rzeczywistości własność okna Delphi jest zerwana i zignorowała właściciela - zamiast tego przynosi to, co chce. –
biorąc pod uwagę tę zaakceptowaną odpowiedź: http://superuser.com/questions/694734/what-does-compatibility-option-disable-visual-themes-do sensownym jest sprawdzenie ['IsCompositionActive'] (https: // msdn.microsoft.com/en-us/library/windows/desktop/bb759811(v=vs.85).aspx) również? Tylko zgadywanie – fantaghirocco