Win32WSDialogs under WinRE
- Lazarus/FPC Version: <Lazarus 2.2.4 (rev lazarus_2_2_4) FPC 3.2.2 x86_64-win64-win32/win64>
- Operating System: <Windows 10>
- CPU / Bitness: <64>
What happens
When a GUI app is built that uses TOpenDialog or TSaveDialog and run under WinRE, as there is no Shell/Explorer, the respective Dialog is not built and shown. An Access Violation is thrown in dialog.Execute.
The TWin32WSXXXDialog.CreateHandle returns INVALID_HANDLE_VALUE. Many of the functions however check for Handle <> 0 - for example TWin32WSXXXDialog.ShowModal. Thus -1 is valid in this context and is cast as IFileXXXDialog and then later an Access Violation is thrown.
Workaround without patching - change Win32Proc.WindowsVersion before working with the respective dialog and revert it afterwards. However if one wishes for having the Vista dialogs when available, one has to further check whether running under WinRE in order to decide whether the workaround is needed.
I patched my build by having CreateHandle fallback to the non-Vista dialogs and then setting a flag (additional boolean var) that interferes with the result from Win32WSDialogs.CanUseVistaDialogs so that CanUseVistaDialogs no longer returns true.
What did you expect
- not to have an Access Violation;
- to have the non-Vista dialog shown.
Steps to reproduce
Important - under WinRE (The bitness should not matter)
procedure TfrmMain.TestClick(Sender: TObject);
var
sd: TSaveDialog;
begin
sd := TSaveDialog.Create(Self);
try
if not sd.Execute then Exit; // Access Violation under WinRE
// ... do something useful ...
finally
sd.Free;
end;
end;