mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-08 08:58:17 +02:00
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:
parent
726ce4d450
commit
cc041a51b2
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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 }
|
||||||
|
Loading…
Reference in New Issue
Block a user