mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-07-20 21:06:00 +02:00
TCustomForm: rewrite MoveToDefaultPosition and fix regression after 5d1e0bb8e9
This commit is contained in:
parent
c187dc8f26
commit
cbafa07331
@ -1217,59 +1217,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomForm.MoveToDefaultPosition;
|
procedure TCustomForm.MoveToDefaultPosition;
|
||||||
var
|
|
||||||
RealWidth, RealHeight: Integer;
|
|
||||||
|
|
||||||
procedure MoveToDefaultMonitor(var X, Y: Integer);
|
|
||||||
var
|
|
||||||
Source, Target: TMonitor;
|
|
||||||
ABounds: TRect;
|
|
||||||
begin
|
|
||||||
// delphi compatibility: if no main form then DefaultMonitor has no effect
|
|
||||||
if Application.MainForm = nil then Exit;
|
|
||||||
// find the monitor of the center of the form (the boundaries might be on another monitor)
|
|
||||||
Source := Screen.MonitorFromRect(Rect(X,Y,X+RealWidth,Y+RealHeight));
|
|
||||||
case DefaultMonitor of
|
|
||||||
dmDesktop:
|
|
||||||
Target := Source; // no need to move
|
|
||||||
dmPrimary:
|
|
||||||
Target := Screen.PrimaryMonitor;
|
|
||||||
dmMainForm:
|
|
||||||
Target := Application.MainForm.Monitor;
|
|
||||||
dmActiveForm:
|
|
||||||
if Screen.ActiveCustomForm <> nil then
|
|
||||||
Target := Screen.ActiveCustomForm.Monitor
|
|
||||||
else
|
|
||||||
Target := Source;
|
|
||||||
end;
|
|
||||||
if Source = Target then Exit; // no move
|
|
||||||
if Position in [poMainFormCenter, poOwnerFormCenter] then
|
|
||||||
begin
|
|
||||||
ABounds := Target.BoundsRect;
|
|
||||||
// shift X and Y from Source to Target monitor
|
|
||||||
X := (X - Source.Left) + ABounds.Left;
|
|
||||||
Y := (Y - Source.Top) + ABounds.Top;
|
|
||||||
// check that we are still in the desired monitor
|
|
||||||
X:= Max(ABounds.Left, Min(ABounds.Right-RealWidth, X));
|
|
||||||
Y:= Max(ABounds.Top, Min(ABounds.Bottom-RealHeight, Y));
|
|
||||||
end
|
|
||||||
else // poWorkAreaCenter, poScreenCenter
|
|
||||||
begin
|
|
||||||
if Position = poWorkAreaCenter then
|
|
||||||
ABounds := Target.WorkareaRect
|
|
||||||
else
|
|
||||||
ABounds := Target.BoundsRect;
|
|
||||||
X := (ABounds.Left + ABounds.Right - RealWidth) div 2;
|
|
||||||
Y := (ABounds.Top + ABounds.Bottom - RealHeight) div 2;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
X, Y: integer;
|
X, Y: integer;
|
||||||
p: TPosition;
|
p: TPosition;
|
||||||
AForm: TCustomForm;
|
BuddyForm: TCustomForm;
|
||||||
RealRect, AFormRealRect: TRect;
|
RealRect, CenterToRect, MonitorRect: TRect;
|
||||||
AFormRealWidth, AFormRealHeight: Integer;
|
m: TMonitor;
|
||||||
|
CheckWorkArea: Boolean;
|
||||||
begin
|
begin
|
||||||
if (Parent <> nil) or (ParentWindow <> 0) then exit;
|
if (Parent <> nil) or (ParentWindow <> 0) then exit;
|
||||||
|
|
||||||
@ -1278,73 +1232,104 @@ begin
|
|||||||
// first make sure X and Y are assigned
|
// first make sure X and Y are assigned
|
||||||
X := Left;
|
X := Left;
|
||||||
Y := Top;
|
Y := Top;
|
||||||
if HandleAllocated and (GetWindowRect(Handle, RealRect) <> 0) then
|
if not (HandleAllocated and (GetWindowRect(Handle, RealRect) <> 0)) then
|
||||||
begin // success
|
RealRect := BoundsRect;
|
||||||
RealWidth := RealRect.Right-RealRect.Left;
|
|
||||||
RealHeight := RealRect.Bottom-RealRect.Top;
|
// process DefaultMonitor
|
||||||
end else
|
case DefaultMonitor of
|
||||||
begin // error
|
dmDesktop: m := nil; // no need to move
|
||||||
RealWidth := Width;
|
dmPrimary: m := Screen.PrimaryMonitor;
|
||||||
RealHeight := Height;
|
dmMainForm:
|
||||||
|
if Application.MainForm <> nil then
|
||||||
|
m := Application.MainForm.Monitor
|
||||||
|
else
|
||||||
|
m := nil;
|
||||||
|
dmActiveForm:
|
||||||
|
if Screen.ActiveCustomForm <> nil then
|
||||||
|
m := Screen.ActiveCustomForm.Monitor
|
||||||
|
else
|
||||||
|
m := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
p := Position;
|
p := Position;
|
||||||
if (Position = poMainFormCenter) and (Application.Mainform=nil) then
|
BuddyForm := nil;
|
||||||
p := poScreenCenter;
|
if p = poOwnerFormCenter then
|
||||||
case P of
|
begin
|
||||||
poDesktopCenter:
|
if Owner is TCustomForm then
|
||||||
begin
|
BuddyForm := TCustomForm(Owner)
|
||||||
X := Screen.DesktopLeft + (Screen.DesktopWidth - RealWidth) div 2;
|
else
|
||||||
Y := Screen.DesktopTop +(Screen.DesktopHeight - RealHeight) div 2;
|
p := poMainFormCenter;
|
||||||
end;
|
end;
|
||||||
poScreenCenter:
|
if p = poMainFormCenter then
|
||||||
begin
|
begin
|
||||||
X := (Screen.Width - RealWidth) div 2;
|
if Assigned(Application.MainForm) then
|
||||||
Y := (Screen.Height - RealHeight) div 2;
|
BuddyForm := Application.MainForm
|
||||||
end;
|
else
|
||||||
poWorkAreaCenter:
|
p := poScreenCenter;
|
||||||
begin
|
end;
|
||||||
X := Screen.WorkAreaLeft + (Screen.WorkAreaWidth - RealWidth) div 2;
|
|
||||||
Y := Screen.WorkAreaTop + (Screen.WorkAreaHeight - RealHeight) div 2;
|
case Position of
|
||||||
end;
|
poScreenCenter..poWorkAreaCenter:
|
||||||
poMainFormCenter,
|
begin
|
||||||
poOwnerFormCenter:
|
CheckWorkArea := True;
|
||||||
begin
|
// decide about the rect to center to
|
||||||
if (P = poOwnerFormCenter) and (Owner is TCustomForm) then
|
CenterToRect := Screen.PrimaryMonitor.BoundsRect; // center by default to primary monitor
|
||||||
AForm := TCustomForm(Owner)
|
case p of
|
||||||
else
|
poScreenCenter:
|
||||||
AForm := Application.MainForm;
|
if Screen.MonitorCount=1 then
|
||||||
if (Self <> AForm) and Assigned(AForm) then
|
CenterToRect := Rect(0, 0, Screen.Width, Screen.Height)
|
||||||
|
else
|
||||||
|
if Assigned(m) then
|
||||||
|
CenterToRect := m.BoundsRect;
|
||||||
|
poDesktopCenter:
|
||||||
|
if Screen.MonitorCount=1 then
|
||||||
|
CenterToRect := Screen.DesktopRect
|
||||||
|
else
|
||||||
|
if Assigned(m) then
|
||||||
|
CenterToRect := m.BoundsRect;
|
||||||
|
poWorkAreaCenter:
|
||||||
|
if Assigned(m) then // WorkArea is always on one monitor - there is no workarea for the whole screen (Screen.WorkAreaRect=PrimaryMonitor.WorkAreaRect)
|
||||||
|
CenterToRect := m.WorkareaRect
|
||||||
|
else
|
||||||
|
CenterToRect := Screen.PrimaryMonitor.WorkareaRect;
|
||||||
|
poMainFormCenter, poOwnerFormCenter:
|
||||||
begin
|
begin
|
||||||
|
if Assigned(m) and (m<>BuddyForm.Monitor) then // DefaultMonitor has precendence before Position
|
||||||
|
CenterToRect := m.BoundsRect
|
||||||
|
else
|
||||||
if FormStyle = fsMDIChild then
|
if FormStyle = fsMDIChild then
|
||||||
begin
|
begin
|
||||||
X := (AForm.ClientWidth - RealWidth) div 2;
|
CenterToRect := BuddyForm.ClientRect;
|
||||||
Y := (AForm.ClientHeight - RealHeight) div 2;
|
CheckWorkArea := False;
|
||||||
end else
|
end else
|
||||||
begin
|
if not (BuddyForm.HandleAllocated and (GetWindowRect(BuddyForm.Handle, CenterToRect) <> 0)) then
|
||||||
if AForm.HandleAllocated and (GetWindowRect(AForm.Handle, AFormRealRect) <> 0) then
|
CenterToRect := Screen.PrimaryMonitor.BoundsRect; // CenterToRect may be zeroed, need to reassign to default value
|
||||||
begin // success
|
|
||||||
AFormRealWidth := AFormRealRect.Right-AFormRealRect.Left;
|
|
||||||
AFormRealHeight := AFormRealRect.Bottom-AFormRealRect.Top;
|
|
||||||
end else
|
|
||||||
begin // error
|
|
||||||
AFormRealWidth := AForm.Width;
|
|
||||||
AFormRealHeight := AForm.Height;
|
|
||||||
end;
|
|
||||||
X := ((AFormRealWidth - RealWidth) div 2) + AForm.Left;
|
|
||||||
Y := ((AFormRealHeight - RealHeight) div 2) + AForm.Top;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
// check that we are still in the viewarea
|
poDesigned..poDefaultSizeOnly: ;
|
||||||
X:= Max(Screen.WorkAreaLeft, Min((Screen.WorkAreaLeft+Screen.WorkAreaWidth)-RealWidth, X));
|
|
||||||
Y:= Max(Screen.WorkAreaTop, Min((Screen.WorkAreaTop+Screen.WorkAreaHeight)-RealHeight, Y));
|
|
||||||
end;
|
end;
|
||||||
|
// center the form
|
||||||
|
X := CenterToRect.Left + (CenterToRect.Width - RealRect.Width) div 2;
|
||||||
|
Y := CenterToRect.Top + (CenterToRect.Height - RealRect.Height) div 2;
|
||||||
|
|
||||||
|
if CheckWorkArea then
|
||||||
|
begin
|
||||||
|
if not Assigned(m) then
|
||||||
|
m := Screen.MonitorFromPoint(Point(X+RealRect.Width div 2, Y+RealRect.Height div 2));
|
||||||
|
if Assigned(m) then
|
||||||
|
MonitorRect := m.WorkareaRect
|
||||||
|
else
|
||||||
|
MonitorRect := Screen.WorkAreaRect;
|
||||||
|
|
||||||
|
X:= Max(MonitorRect.Left, Min(MonitorRect.Right-RealRect.Width, X));
|
||||||
|
Y:= Max(MonitorRect.Top, Min(MonitorRect.Bottom-RealRect.Height, Y));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
poDefault, poDefaultPosOnly:
|
||||||
|
if HandleAllocated then // get current widgetset position
|
||||||
|
GetWindowRelativePosition(Handle,X,Y);
|
||||||
|
poDesigned, poDefaultSizeOnly: ;
|
||||||
end;
|
end;
|
||||||
// get current widgetset position
|
|
||||||
if (p in [poDefault, poDefaultPosOnly]) and HandleAllocated then
|
|
||||||
GetWindowRelativePosition(Handle,X,Y);
|
|
||||||
if (Position in [poScreenCenter, poMainFormCenter, poOwnerFormCenter, poWorkAreaCenter]) then
|
|
||||||
MoveToDefaultMonitor(X, Y);
|
|
||||||
SetBounds(X, Y, Width, Height);
|
SetBounds(X, Y, Width, Height);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user