Dialogs: fix several issues with OnShow/OnCanClose/OnClose events.

- fixes showing OnShow twice
- fixes not firing TSelectDirectoryDialog.OnClose on WinXP
- fixes wrong Sender in TFindDialog.OnShow
- fixes firing TFontDialog.OnShow after fom closes (Windows)
- fixes not firing OnShow and OnClose of TCalculatorDialog
- fixes wrong Sender in TCalendarDialog.OnShow and OnCanClose
- call DoXXX instead of OnXXX wherever possible
- more conditioal debug output
Resolves issue #0023065.
Partly resolves issue #0021163.

git-svn-id: trunk@52801 -
This commit is contained in:
bart 2016-08-13 18:05:25 +00:00
parent 726ce4d450
commit cc041a51b2
5 changed files with 105 additions and 18 deletions

View File

@ -68,7 +68,9 @@ type
FTitle : string; FTitle : string;
FUserChoice: integer; FUserChoice: integer;
FHelpContext: THelpContext; FHelpContext: THelpContext;
FCanCloseCalled: Boolean; FDoCanCloseCalled: Boolean;
FDoShowCalled: Boolean;
FDoCloseCalled: Boolean;
FClosing: boolean; FClosing: boolean;
procedure SetHandle(const AValue: THandle); procedure SetHandle(const AValue: THandle);
function IsTitleStored: boolean; function IsTitleStored: boolean;
@ -80,6 +82,7 @@ type
function GetWidth: Integer; virtual; function GetWidth: Integer; virtual;
procedure SetHeight(const AValue: integer); virtual; procedure SetHeight(const AValue: integer); virtual;
procedure SetWidth(const AValue: integer); virtual; procedure SetWidth(const AValue: integer); virtual;
procedure ResetShowCloseFlags;
public public
FCompStyle : LongInt; FCompStyle : LongInt;
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;

View File

@ -148,6 +148,8 @@ type
procedure SetDialogScale(AValue: integer); procedure SetDialogScale(AValue: integer);
protected protected
class procedure WSRegisterClass; override; class procedure WSRegisterClass; override;
procedure OnDialogClose(Sender: TObject; var CloseAction: TCloseAction);
procedure OnDialogShow(Sender: TObject);
procedure Change; virtual; procedure Change; virtual;
procedure CalcKey(var Key: char); virtual; procedure CalcKey(var Key: char); virtual;
function DefaultTitle: string; override; function DefaultTitle: string; override;
@ -193,6 +195,7 @@ type
FCalendar: TCalendar; FCalendar: TCalendar;
procedure OnDialogClose(Sender: TObject; var CloseAction: TCloseAction); procedure OnDialogClose(Sender: TObject; var CloseAction: TCloseAction);
procedure OnDialogCloseQuery(Sender : TObject; var CanClose : boolean); procedure OnDialogCloseQuery(Sender : TObject; var CanClose : boolean);
procedure OnDialogShow(Sender: TObject);
procedure OnCalendarDayChanged(Sender: TObject); procedure OnCalendarDayChanged(Sender: TObject);
procedure OnCalendarMonthChanged(Sender: TObject); procedure OnCalendarMonthChanged(Sender: TObject);
procedure OnCalendarYearChanged(Sender: TObject); procedure OnCalendarYearChanged(Sender: TObject);
@ -540,6 +543,17 @@ begin
RegisterCalculatorDialog; RegisterCalculatorDialog;
end; end;
procedure TCalculatorDialog.OnDialogClose(Sender: TObject;
var CloseAction: TCloseAction);
begin
DoClose;
end;
procedure TCalculatorDialog.OnDialogShow(Sender: TObject);
begin
DoShow;
end;
function TCalculatorDialog.GetDisplay: Double; function TCalculatorDialog.GetDisplay: Double;
begin begin
if Assigned(DlgForm) then if Assigned(DlgForm) then
@ -592,8 +606,11 @@ begin
DlgForm:=CreateCalculatorForm(Application, FLayout, HelpContext); DlgForm:=CreateCalculatorForm(Application, FLayout, HelpContext);
try try
ResetShowCloseFlags;
(DlgForm as TCalculatorForm).OnCalcKey:= @Self.CalcKey; (DlgForm as TCalculatorForm).OnCalcKey:= @Self.CalcKey;
(DlgForm as TCalculatorForm).OnDisplayChange:= @Self.DisplayChange; (DlgForm as TCalculatorForm).OnDisplayChange:= @Self.DisplayChange;
(DlgForm as TCalculatorForm).OnShow := @Self.OnDialogShow;
(DlgForm as TCalculatorForm).OnClose := @Self.OnDialogClose;
if FDialogScale<>100 then if FDialogScale<>100 then
DlgForm.ScaleBy(FDialogScale,100); DlgForm.ScaleBy(FDialogScale,100);
@ -689,13 +706,20 @@ end;
procedure TCalendarDialog.OnDialogClose(Sender: TObject; procedure TCalendarDialog.OnDialogClose(Sender: TObject;
var CloseAction: TCloseAction); var CloseAction: TCloseAction);
begin begin
if Assigned(OnClose) then OnClose(Self); //if Assigned(OnClose) then OnClose(Self);
DoClose;
end; end;
procedure TCalendarDialog.OnDialogCloseQuery(Sender: TObject; procedure TCalendarDialog.OnDialogCloseQuery(Sender: TObject;
var CanClose: boolean); var CanClose: boolean);
begin begin
if Assigned(OnCanClose) then OnCanClose(Sender, CanClose); //if Assigned(OnCanClose) then OnCanClose(Sender, CanClose);
DoCanClose(CanClose);
end;
procedure TCalendarDialog.OnDialogShow(Sender: TObject);
begin
DoShow;
end; end;
procedure TCalendarDialog.OnCalendarDayChanged(Sender: TObject); procedure TCalendarDialog.OnCalendarDayChanged(Sender: TObject);
@ -739,6 +763,7 @@ var
begin begin
DlgForm:=TForm.CreateNew(Application, 0); DlgForm:=TForm.CreateNew(Application, 0);
try try
ResetShowCloseFlags;
DlgForm.DisableAlign; DlgForm.DisableAlign;
DlgForm.Caption:=Title; DlgForm.Caption:=Title;
if (csDesigning in ComponentState) then if (csDesigning in ComponentState) then
@ -755,7 +780,7 @@ begin
DlgForm.BorderStyle:=bsDialog; DlgForm.BorderStyle:=bsDialog;
DlgForm.AutoScroll:=false; DlgForm.AutoScroll:=false;
DlgForm.AutoSize:=true; DlgForm.AutoSize:=true;
DlgForm.OnShow:=Self.OnShow; DlgForm.OnShow := @OnDialogShow;
DlgForm.OnClose:=@OnDialogClose; DlgForm.OnClose:=@OnDialogClose;
DlgForm.OnCloseQuery:=@OnDialogCloseQuery; DlgForm.OnCloseQuery:=@OnDialogCloseQuery;
@ -832,4 +857,5 @@ begin
end; end;
end; end;
end. end.

View File

@ -35,6 +35,7 @@ begin
DisabledList := Screen.DisableForms(Screen.ActiveForm); DisabledList := Screen.DisableForms(Screen.ActiveForm);
try try
FUserChoice := mrNone; FUserChoice := mrNone;
ResetShowCloseFlags;
Handle := TWSCommonDialogClass(WidgetSetClass).CreateHandle(Self); Handle := TWSCommonDialogClass(WidgetSetClass).CreateHandle(Self);
Result:= DoExecute; Result:= DoExecute;
Close; Close;
@ -54,6 +55,7 @@ procedure TCommonDialog.Close;
begin begin
if HandleAllocated and not FClosing then begin if HandleAllocated and not FClosing then begin
FClosing := true; FClosing := true;
if not FDoCloseCalled then
DoClose; DoClose;
TWSCommonDialogClass(WidgetSetClass).DestroyHandle(Self); TWSCommonDialogClass(WidgetSetClass).DestroyHandle(Self);
FHandle := 0; FHandle := 0;
@ -63,18 +65,22 @@ end;
procedure TCommonDialog.DoShow; procedure TCommonDialog.DoShow;
begin begin
if FDoShowCalled then Exit;
FDoShowCalled := True;
if Assigned(FOnShow) then FOnShow(Self); if Assigned(FOnShow) then FOnShow(Self);
end; end;
procedure TCommonDialog.DoCanClose(var CanClose: Boolean); procedure TCommonDialog.DoCanClose(var CanClose: Boolean);
begin begin
FCanCloseCalled := True; FDoCanCloseCalled := True;
if Assigned(FOnCanClose) then if Assigned(FOnCanClose) then
OnCanClose(Self, CanClose); OnCanClose(Self, CanClose);
end; end;
procedure TCommonDialog.DoClose; procedure TCommonDialog.DoClose;
begin begin
if FDoCloseCalled then Exit;
FDoCloseCalled := True;
if Assigned(FOnClose) then FOnClose(Self); if Assigned(FOnClose) then FOnClose(Self);
end; end;
@ -111,35 +117,52 @@ begin
FWidth:=AValue; FWidth:=AValue;
end; end;
procedure TCommonDialog.ResetShowCloseFlags;
begin
FDoShowCalled := False;
FDoCanCloseCalled := False;
FDoCloseCalled := False;
end;
function TCommonDialog.DoExecute : boolean; function TCommonDialog.DoExecute : boolean;
var var
CanClose: boolean; CanClose: boolean;
begin begin
FCanCloseCalled := False; {$ifdef DebugCommonDialogEvents}
if Assigned(FOnShow) then debugln(['TCommonDialog.DoExecute A']);
FOnShow(Self); {$endif}
if not FDoShowCalled then
begin
{$ifdef DebugCommonDialogEvents}
debugln(['TCommonDialog.DoExecute calling DoShow']);
{$endif}
DoShow;
end;
{$ifdef DebugCommonDialogEvents}
debugln(['TCommonDialog.DoExecute before WS_ShowModal']);
{$endif}
TWSCommonDialogClass(WidgetSetClass).ShowModal(Self); TWSCommonDialogClass(WidgetSetClass).ShowModal(Self);
{$ifdef DebugCommonDialogEvents} {$ifdef DebugCommonDialogEvents}
if (Self is TFileDialog) then debugln(['TCommonDialog.DoExecute, FCanCloseCalled=',FCanCloseCalled,' FUserChoice=',ModalResultStr[FUserChoice]]); debugln(['TCommonDialog.DoExecute after WS_ShowModal, FCanCloseCalled=',FDoCanCloseCalled,' FUserChoice=',ModalResultStr[FUserChoice]]);
{$endif} {$endif}
// can close was called from widgetset loop // can close was called from widgetset loop
if not FCanCloseCalled then if not FDoCanCloseCalled then
begin begin
repeat repeat
{$ifdef DebugCommonDialogEvents} {$ifdef DebugCommonDialogEvents}
if (Self is TFileDialog) then debugln(['TCommonDialog.DoExecute, FUserChoice=',ModalResultStr[FUserChoice],' Handle=',Handle]); debugln(['TCommonDialog.DoExecute, FUserChoice=',ModalResultStr[FUserChoice],' Handle=',Handle]);
{$endif} {$endif}
if (FUserChoice <> mrNone) and (Handle<>0) then if (FUserChoice <> mrNone) and (Handle<>0) then
begin begin
CanClose := True; CanClose := True;
{$ifdef DebugCommonDialogEvents} {$ifdef DebugCommonDialogEvents}
if (Self is TFileDialog) then debugln(['TCommonDialog.DoExecute calling DoCanClose']); debugln(['TCommonDialog.DoExecute calling DoCanClose']);
{$endif} {$endif}
DoCanClose(CanClose); DoCanClose(CanClose);
if not CanClose then if not CanClose then
FUserChoice:=mrNone; FUserChoice:=mrNone;
{$ifdef DebugCommonDialogEvents} {$ifdef DebugCommonDialogEvents}
if (Self is TFileDialog) then debugln(['TCommonDialog.DoExecute after calling DoCanClose: CanClose=',CanClose,' FUserChoice=',ModalResultStr[FUserChoice]]); debugln(['TCommonDialog.DoExecute after calling DoCanClose: CanClose=',CanClose,' FUserChoice=',ModalResultStr[FUserChoice]]);
{$endif} {$endif}
end; end;
if FUserChoice <> mrNone then if FUserChoice <> mrNone then
@ -150,6 +173,9 @@ begin
until false; until false;
end; end;
Result := (FUserChoice = mrOk); Result := (FUserChoice = mrOk);
{$ifdef DebugCommonDialogEvents}
debugln(['TCommonDialog.DoExecute End']);
{$endif}
end; end;
function TCommonDialog.DefaultTitle: string; function TCommonDialog.DefaultTitle: string;

View File

@ -46,7 +46,7 @@ begin
inherited DoCanClose(CanClose) inherited DoCanClose(CanClose)
else else
begin begin
FCanCloseCalled := True; FDoCanCloseCalled := True;
CanClose := True; CanClose := True;
end; end;
end; end;
@ -441,7 +441,7 @@ begin
inherited DoCanClose(CanClose) inherited DoCanClose(CanClose)
else else
begin begin
FCanCloseCalled := True; FDoCanCloseCalled := True;
CanClose := True; CanClose := True;
end; end;
end; end;

View File

@ -521,6 +521,9 @@ begin
CDN_INITDONE: CDN_INITDONE:
begin begin
ExtractDataFromNotify; ExtractDataFromNotify;
{$ifdef DebugCommonDialogEvents}
debugln(['OpenFileDialogCallBack calling DoShow']);
{$endif}
TOpenDialog(DlgRec^.Dialog).DoShow; TOpenDialog(DlgRec^.Dialog).DoShow;
end; end;
CDN_SELCHANGE: CDN_SELCHANGE:
@ -887,6 +890,9 @@ begin
FileDialogEvents := TFileDialogEvents.Create(AOpenDialog); FileDialogEvents := TFileDialogEvents.Create(AOpenDialog);
ADialog.Advise(FileDialogEvents, @Cookie); ADialog.Advise(FileDialogEvents, @Cookie);
try try
{$ifdef DebugCommonDialogEvents}
debugln('TWin32WSOpenDialog.VistaDialogShowModal calling DoShow');
{$endif}
AOpenDialog.DoShow; AOpenDialog.DoShow;
ADialog.Show(GetParentWnd); ADialog.Show(GetParentWnd);
{$ifdef DebugCommonDialogEvents} {$ifdef DebugCommonDialogEvents}
@ -1119,6 +1125,10 @@ begin
nSizeMax := MaxFontSize; nSizeMax := MaxFontSize;
end; end;
end; end;
{$ifdef DebugCommonDialogEvents}
debugln(['TWin32WSFontDialog.CreateHandle calling DoShow']);
{$endif}
TFontDialog(ACommonDialog).DoShow;
UserResult := ChooseFontW(@CFW); UserResult := ChooseFontW(@CFW);
// we need to update LF now // we need to update LF now
LF.lfFaceName := UTF16ToUTF8(LFW.lfFaceName); LF.lfFaceName := UTF16ToUTF8(LFW.lfFaceName);
@ -1133,7 +1143,10 @@ begin
Color := CF.RGBColors; Color := CF.RGBColors;
end; end;
end; end;
{$ifdef DebugCommonDialogEvents}
debugln(['TWin32WSFontDialog.CreateHandle calling DoClose']);
{$endif}
TFontDialog(ACommonDialog).DoClose;
Result := 0; Result := 0;
end; end;
@ -1208,6 +1221,9 @@ var
Title: widestring; Title: widestring;
DirName: string; DirName: string;
begin begin
{$ifdef DebugCommonDialogEvents}
debugln(['TWin32WSSelectDirectoryDialog.CreateOldHandle A']);
{$endif}
DirName := ''; DirName := '';
InitialDir := TSelectDirectoryDialog(ACommonDialog).FileName; InitialDir := TSelectDirectoryDialog(ACommonDialog).FileName;
Options := TSelectDirectoryDialog(ACommonDialog).Options; Options := TSelectDirectoryDialog(ACommonDialog).Options;
@ -1241,8 +1257,17 @@ begin
// this value will be passed to callback proc as lpData // this value will be passed to callback proc as lpData
lParam := Windows.LParam(PWideChar(InitialDirW)); lParam := Windows.LParam(PWideChar(InitialDirW));
end; end;
{$ifdef DebugCommonDialogEvents}
debugln(['TWin32WSSelectDirectoryDialog.CreateOldHandle calling DoShow']);
{$endif}
TSelectDirectoryDialog(ACommonDialog).DoShow;
{$ifdef DebugCommonDialogEvents}
debugln(['TWin32WSSelectDirectoryDialog.CreateOldHandle before SHBrowseForFolder']);
{$endif}
iidl := SHBrowseForFolderW(@biw); iidl := SHBrowseForFolderW(@biw);
{$ifdef DebugCommonDialogEvents}
debugln(['TWin32WSSelectDirectoryDialog.CreateOldHandle after SHBrowseForFolder']);
{$endif}
if Assigned(iidl) then if Assigned(iidl) then
begin begin
@ -1260,7 +1285,14 @@ begin
CoTaskMemFree(Buffer); CoTaskMemFree(Buffer);
{$ifdef DebugCommonDialogEvents}
debugln(['TWin32WSSelectDirectoryDialog.CreateOldHandle calling DoClose']);
{$endif}
TSelectDirectoryDialog(ACommonDialog).DoClose;
Result := 0; Result := 0;
{$ifdef DebugCommonDialogEvents}
debugln(['TWin32WSSelectDirectoryDialog.CreateOldHandle End']);
{$endif}
end; end;
{ TFileDialogEvents } { TFileDialogEvents }