LCL: Fix changing TForm's bounds and WindowState etc. Issue #36127, patch from Joeny Ang.

git-svn-id: trunk@63888 -
This commit is contained in:
juha 2020-09-18 09:33:43 +00:00
parent b3cbbc6218
commit 54661a2a36
4 changed files with 49 additions and 14 deletions

View File

@ -493,6 +493,7 @@ type
FDelayedEventCtr: Integer; FDelayedEventCtr: Integer;
FDelayedOnChangeBounds, FDelayedOnResize: Boolean; FDelayedOnChangeBounds, FDelayedOnResize: Boolean;
FIsFirstOnShow, FIsFirstOnActivate: Boolean; FIsFirstOnShow, FIsFirstOnActivate: Boolean;
FIsFirstRestore, FWindowStateChanged: Boolean;
function GetClientHandle: HWND; function GetClientHandle: HWND;
function GetEffectiveShowInTaskBar: TShowInTaskBar; function GetEffectiveShowInTaskBar: TShowInTaskBar;
function GetMonitor: TMonitor; function GetMonitor: TMonitor;

View File

@ -706,7 +706,7 @@ begin
end; end;
{ call onShow() or onActivate() for the first time, { call onShow() or onActivate() for the first time,
after first OnResize() and OnChangeBounds() } after first OnResize() and OnChangeBounds() }
if FDelayedOnResize or FDelayedOnChangeBounds then if (FDelayedOnResize or FDelayedOnChangeBounds) and FActive then
begin begin
if FIsFirstOnShow then if FIsFirstOnShow then
begin begin
@ -716,18 +716,20 @@ begin
if FIsFirstOnActivate then if FIsFirstOnActivate then
begin begin
FIsFirstOnActivate := False; FIsFirstOnActivate := False;
if FActive then Activate;
Activate;
end; end;
end; end;
{ delayed onResize() } if not (FIsFirstOnShow or FIsFirstOnActivate) then
if FDelayedOnResize then begin
inherited DoOnResize; { delayed onResize() }
{ delayed onChangeBounds() } if FDelayedOnResize then
if FDelayedOnResize or FDelayedOnChangeBounds then inherited DoOnResize;
inherited DoOnChangeBounds; { delayed onChangeBounds() }
FDelayedOnChangeBounds := False; if FDelayedOnResize or FDelayedOnChangeBounds then
FDelayedOnResize := False; inherited DoOnChangeBounds;
FDelayedOnChangeBounds := False;
FDelayedOnResize := False;
end;
end; end;
procedure TCustomForm.WMWindowPosChanged(var Message: TLMWindowPosChanged); procedure TCustomForm.WMWindowPosChanged(var Message: TLMWindowPosChanged);
@ -1001,6 +1003,7 @@ begin
if FIsFirstOnShow and (WindowState in [wsMaximized, wsFullScreen]) then if FIsFirstOnShow and (WindowState in [wsMaximized, wsFullScreen]) then
Exit; Exit;
FIsFirstOnShow := False; FIsFirstOnShow := False;
FIsFirstRestore := WindowState in [wsMaximized, wsFullScreen];
if Assigned(FOnShow) then FOnShow(Self); if Assigned(FOnShow) then FOnShow(Self);
end; end;
@ -1148,8 +1151,28 @@ begin
if (OldState = wsMinimized) and (Application.MainForm = Self) and if (OldState = wsMinimized) and (Application.MainForm = Self) and
(WidgetSet.GetLCLCapability(lcNeedMininimizeAppWithMainForm) <> LCL_CAPABILITY_NO) then (WidgetSet.GetLCLCapability(lcNeedMininimizeAppWithMainForm) <> LCL_CAPABILITY_NO) then
Application.Restore; Application.Restore;
if Assigned(OnWindowStateChange) then end;
OnWindowStateChange(Self);
if (OldState <> State) or FWindowStateChanged then
begin
{ honor Position property on first restore when form was designed maximized }
if not (FIsFirstOnShow or FIsFirstOnActivate) then
begin
if FIsFirstRestore and (State = wsNormal) then
begin
{ Need to check width/height before calling MoveToDefaultPosition.
QT5 triggers Resizing() twice: one for position change, and
another for size change. This check should not affect other
widgetsets. }
if (Width <> RestoredWidth) or (Height <> RestoredHeight) then
Exit;
MoveToDefaultPosition;
FIsFirstRestore := False;
end;
if Assigned(OnWindowStateChange) then
OnWindowStateChange(Self);
end;
FWindowStateChanged := False;
end; end;
end; end;
end; end;
@ -1830,7 +1853,10 @@ begin
FWindowState := Value; FWindowState := Value;
//DebugLn(['TCustomForm.SetWindowState ',DbgSName(Self),' ',ord(FWindowState),' csDesigning=',csDesigning in ComponentState,' Showing=',Showing]); //DebugLn(['TCustomForm.SetWindowState ',DbgSName(Self),' ',ord(FWindowState),' csDesigning=',csDesigning in ComponentState,' Showing=',Showing]);
if (not (csDesigning in ComponentState)) and Showing then if (not (csDesigning in ComponentState)) and Showing then
begin
FWindowStateChanged := True;
ShowWindow(Handle, ShowCommands[Value]); ShowWindow(Handle, ShowCommands[Value]);
end;
end; end;
end; end;
@ -2030,6 +2056,8 @@ begin
FDelayedOnResize := False; FDelayedOnResize := False;
FIsFirstOnShow := True; FIsFirstOnShow := True;
FIsFirstOnActivate := True; FIsFirstOnActivate := True;
FIsFirstRestore := False;
FWindowStateChanged := False;
GlobalNameSpace.BeginWrite; GlobalNameSpace.BeginWrite;
try try
CreateNew(AOwner, 1); // this calls BeginFormUpdate, which is ended in AfterConstruction CreateNew(AOwner, 1); // this calls BeginFormUpdate, which is ended in AfterConstruction

View File

@ -1121,6 +1121,8 @@ begin
{$ENDIF} {$ENDIF}
SizeMsg.SizeType := SIZE_MINIMIZED; SizeMsg.SizeType := SIZE_MINIMIZED;
end end
else if (GDK_WINDOW_STATE_FULLSCREEN and state^.new_window_state)>0 then
SizeMsg.SizeType := SIZE_FULLSCREEN
else if (GDK_WINDOW_STATE_MAXIMIZED and state^.new_window_state)>0 then else if (GDK_WINDOW_STATE_MAXIMIZED and state^.new_window_state)>0 then
begin begin
// it can be both maximized + iconified and just loose iconified state // it can be both maximized + iconified and just loose iconified state
@ -1133,7 +1135,8 @@ begin
// don't bother the LCL if nothing changed // don't bother the LCL if nothing changed
case SizeMsg.SizeType of case SizeMsg.SizeType of
SIZE_RESTORED: if TheForm.WindowState=wsNormal then exit; SIZE_RESTORED: if TheForm.WindowState=wsNormal then exit;
SIZE_MINIMIZED: if TheForm.WindowState=wsMinimized then exit; // Need to send LM_SIZE message to LCL if wsMinimized to trigger onWindowStateChange()
//SIZE_MINIMIZED: if TheForm.WindowState=wsMinimized then exit;
SIZE_MAXIMIZED: if TheForm.WindowState=wsMaximized then exit; SIZE_MAXIMIZED: if TheForm.WindowState=wsMaximized then exit;
SIZE_FULLSCREEN: if TheForm.WindowState=wsFullScreen then exit; SIZE_FULLSCREEN: if TheForm.WindowState=wsFullScreen then exit;
end; end;

View File

@ -15,6 +15,7 @@
{$ENDIF} {$ENDIF}
type type
TWinControlAccess = class(TWinControl); TWinControlAccess = class(TWinControl);
TApplicationAccess = class(TApplication);
{*************************************************************} {*************************************************************}
{ callback routines } { callback routines }
{*************************************************************} {*************************************************************}
@ -2054,6 +2055,8 @@ begin
begin begin
CheckSynchronize; CheckSynchronize;
TWin32Widgetset(Widgetset).CheckPipeEvents; TWin32Widgetset(Widgetset).CheckPipeEvents;
if Assigned(Application) then
TApplicationAccess(Application).ProcessAsyncCallQueue;
end; end;
WM_ENTERIDLE: Application.Idle(False); WM_ENTERIDLE: Application.Idle(False);
WM_ACTIVATE: SetLMessageAndParams(LM_ACTIVATE); WM_ACTIVATE: SetLMessageAndParams(LM_ACTIVATE);