From 4213e0848c718fa9be1e3c9320d25b25c7e404d8 Mon Sep 17 00:00:00 2001 From: bart <9132501-flyingsheep@users.noreply.gitlab.com> Date: Sun, 21 Aug 2016 11:45:58 +0000 Subject: [PATCH] Dialogs: - implement a mechanisme to query the widgetset how and when to handle DoShow, DoCanClose and DoClose. - implement QueryWSEventCapabilities for Win32 widgetset git-svn-id: trunk@52850 - --- lcl/dialogs.pp | 5 ++++ lcl/include/commondialog.inc | 16 ++++++++--- lcl/interfaces/win32/win32wsdialogs.pp | 38 ++++++++++++++++++++++++++ lcl/widgetset/wsdialogs.pp | 7 +++++ 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/lcl/dialogs.pp b/lcl/dialogs.pp index 3485aa3f95..29f9f884ea 100644 --- a/lcl/dialogs.pp +++ b/lcl/dialogs.pp @@ -58,6 +58,10 @@ type { TCommonDialog } + TCDWSEventCapability = (cdecWSPerformsDoShow, cdecWSPerformsDoCanClose, cdecWSPerformsDoClose, + cdecWSNOCanCloseSupport); + TCDWSEventCapabilities = set of TCDWSEventCapability; + TCommonDialog = class(TLCLComponent) private FHandle : THandle; @@ -72,6 +76,7 @@ type FDoShowCalled: Boolean; FDoCloseCalled: Boolean; FClosing: boolean; + FWSEventCapabilities :TCDWSEventCapabilities; procedure SetHandle(const AValue: THandle); function IsTitleStored: boolean; protected diff --git a/lcl/include/commondialog.inc b/lcl/include/commondialog.inc index bfc37ef2e9..889a8aca66 100644 --- a/lcl/include/commondialog.inc +++ b/lcl/include/commondialog.inc @@ -36,6 +36,7 @@ begin try FUserChoice := mrNone; ResetShowCloseFlags; + FWSEventCapabilities := TWSCommonDialogClass(WidgetSetClass).QueryWSEventCapabilities(Self); Handle := TWSCommonDialogClass(WidgetSetClass).CreateHandle(Self); Result:= DoExecute; Close; @@ -55,7 +56,7 @@ procedure TCommonDialog.Close; begin if HandleAllocated and not FClosing then begin FClosing := true; - if not FDoCloseCalled then + if (not FDoCloseCalled) and (not (cdecWSPerformsDoClose in FWSEventCapabilities)) then DoClose; TWSCommonDialogClass(WidgetSetClass).DestroyHandle(Self); FHandle := 0; @@ -73,7 +74,7 @@ end; procedure TCommonDialog.DoCanClose(var CanClose: Boolean); begin FDoCanCloseCalled := True; - if Assigned(FOnCanClose) then + if Assigned(FOnCanClose) and (not (cdecWSNOCanCloseSupport in FWSEventCapabilities)) then OnCanClose(Self, CanClose); end; @@ -128,10 +129,17 @@ function TCommonDialog.DoExecute : boolean; var CanClose: boolean; begin + { + Various widgetsets may or may not call DoShow, DoCanClose or DoClose from within + the WS implementation. + If the WS calls any of these, we assume that we should NOT call them from here. + Checking for FDoShowCalled (etc) alone is not enough, since it may very well be that + the WS wants to (deiberately) call the methos at a later point in time. + } {$ifdef DebugCommonDialogEvents} debugln(['TCommonDialog.DoExecute A']); {$endif} - if not FDoShowCalled then + if (not FDoShowCalled) and (not (cdecWSPerformsDoShow in FWSEventCapabilities)) then begin {$ifdef DebugCommonDialogEvents} debugln(['TCommonDialog.DoExecute calling DoShow']); @@ -146,7 +154,7 @@ begin debugln(['TCommonDialog.DoExecute after WS_ShowModal, FCanCloseCalled=',FDoCanCloseCalled,' FUserChoice=',ModalResultStr[FUserChoice]]); {$endif} // can close was called from widgetset loop - if not FDoCanCloseCalled then + if (not FDoCanCloseCalled) and ((FWSEventCapabilities * [cdecWSPerformsDoCanClose,cdecWSNOCanCloseSupport]) = []) then begin repeat {$ifdef DebugCommonDialogEvents} diff --git a/lcl/interfaces/win32/win32wsdialogs.pp b/lcl/interfaces/win32/win32wsdialogs.pp index 73da5cfb3b..6f69083820 100644 --- a/lcl/interfaces/win32/win32wsdialogs.pp +++ b/lcl/interfaces/win32/win32wsdialogs.pp @@ -82,6 +82,7 @@ type class function CreateHandle(const ACommonDialog: TCommonDialog): THandle; override; class procedure DestroyHandle(const ACommonDialog: TCommonDialog); override; class procedure ShowModal(const ACommonDialog: TCommonDialog); override; + class function QueryWSEventCapabilities(const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; override; end; { TWin32WSSaveDialog } @@ -91,6 +92,7 @@ type class function CreateHandle(const ACommonDialog: TCommonDialog): THandle; override; class procedure DestroyHandle(const ACommonDialog: TCommonDialog); override; class procedure ShowModal(const ACommonDialog: TCommonDialog); override; + class function QueryWSEventCapabilities(const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; override; end; { TWin32WSSelectDirectoryDialog } @@ -100,6 +102,7 @@ type class function CreateOldHandle(const ACommonDialog: TCommonDialog): THandle; published class function CreateHandle(const ACommonDialog: TCommonDialog): THandle; override; + class function QueryWSEventCapabilities(const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; override; end; { TWin32WSColorDialog } @@ -109,6 +112,7 @@ type class function CreateHandle(const ACommonDialog: TCommonDialog): THandle; override; class procedure ShowModal(const ACommonDialog: TCommonDialog); override; class procedure DestroyHandle(const ACommonDialog: TCommonDialog); override; + class function QueryWSEventCapabilities(const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; override; end; { TWin32WSColorButton } @@ -122,6 +126,7 @@ type TWin32WSFontDialog = class(TWSFontDialog) published class function CreateHandle(const ACommonDialog: TCommonDialog): THandle; override; + class function QueryWSEventCapabilities(const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; override; end; @@ -411,6 +416,12 @@ begin end; end; +class function TWin32WSColorDialog.QueryWSEventCapabilities( + const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; +begin + Result := [cdecWSNoCanCloseSupport]; +end; + procedure UpdateStorage(Wnd: HWND; OpenFile: LPOPENFILENAME); var FilesSize: SizeInt; @@ -997,6 +1008,12 @@ begin end; end; +class function TWin32WSOpenDialog.QueryWSEventCapabilities( + const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; +begin + Result := [cdecWSPerformsDoShow,cdecWSPerformsDoCanClose]; +end; + { TWin32WSSaveDialog } class function TWin32WSSaveDialog.CreateHandle(const ACommonDialog: TCommonDialog): THandle; @@ -1065,6 +1082,12 @@ begin end; end; +class function TWin32WSSaveDialog.QueryWSEventCapabilities( + const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; +begin + Result := [cdecWSPerformsDoShow,cdecWSPerformsDoCanClose]; +end; + { TWin32WSFontDialog } class function TWin32WSFontDialog.CreateHandle(const ACommonDialog: TCommonDialog): THandle; @@ -1150,6 +1173,12 @@ begin Result := 0; end; +class function TWin32WSFontDialog.QueryWSEventCapabilities( + const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; +begin + Result := [cdecWSPerformsDoShow, cdecWSPerformsDoClose, cdecWSNoCanCloseSupport]; +end; + { TWin32WSCommonDialog } class function TWin32WSCommonDialog.CreateHandle(const ACommonDialog: TCommonDialog): THandle; @@ -1208,6 +1237,15 @@ begin Result := CreateOldHandle(ACommonDialog); end; +class function TWin32WSSelectDirectoryDialog.QueryWSEventCapabilities( + const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; +begin + if CanUseVistaDialogs(TSelectDirectoryDialog(ACommonDialog)) then + Result := [cdecWSPerformsDoShow,cdecWSPerformsDoCanClose] + else + Result := [cdecWSPerformsDoShow, cdecWSPerformsDoClose, cdecWSNoCanCloseSupport]; +end; + class function TWin32WSSelectDirectoryDialog.CreateOldHandle( const ACommonDialog: TCommonDialog): THandle; var diff --git a/lcl/widgetset/wsdialogs.pp b/lcl/widgetset/wsdialogs.pp index 76a51c8a16..3cebc0e700 100644 --- a/lcl/widgetset/wsdialogs.pp +++ b/lcl/widgetset/wsdialogs.pp @@ -51,6 +51,7 @@ type class function CreateHandle(const ACommonDialog: TCommonDialog): THandle; virtual; class procedure ShowModal(const ACommonDialog: TCommonDialog); virtual; class procedure DestroyHandle(const ACommonDialog: TCommonDialog); virtual; + class function QueryWSEventCapabilities(const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; virtual; end; { TWSFileDialog } @@ -120,6 +121,12 @@ class procedure TWSCommonDialog.DestroyHandle(const ACommonDialog: TCommonDialog begin end; +class function TWSCommonDialog.QueryWSEventCapabilities( + const ACommonDialog: TCommonDialog): TCDWSEventCapabilities; +begin + Result := []; +end; + class procedure TWSCommonDialog.ShowModal(const ACommonDialog: TCommonDialog); begin end;