Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/VCL/Core VCL Classes/TForm    [ Add a report in this area ]  
Report #:  61539   Status: Open
poMainFormCenter does not work sometimes
Project:  Delphi Build #:  11.0.2902.10471
Version:    11.0 Submitted By:   Qian Xu
Report Type:  Basic functionality failure Date Reported:  4/28/2008 8:54:07 PM
Severity:    Commonly encountered problem Last Updated: 7/17/2009 7:58:29 PM
Platform:    All platforms Internal Tracking #:   260183
Resolution: None (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
Description
When 50% main form is out of screen (or on secondary monitor), any sub-form (with Position=poMainFormCenter) might be invisible.

I have attached a patch. See below
Steps to Reproduce:
None
Workarounds
{$IFDEF FIXUP_FORM_POPUP_POSITION}
function GetPrimaryMonitor: TMonitor;
var
  I: Integer;
begin
  for I := 0 to Screen.MonitorCount - 1 do
  begin
    Result := Screen.Monitors[I];
    if Result.Primary then
      Exit;
  end;
  Result := Screen.Monitors[0];
end;

procedure CenterFormToPrimaryMonitorCenter(var X, Y: Integer; AForm: TCustomForm);
var
  R: TRect;
begin
  R := GetPrimaryMonitor.WorkareaRect;
  X := R.Left + (R.Right - R.Left - AForm.Width) div 2;
  Y := R.Top + (R.Bottom - R.Top - AForm.Height) div 2;
end;

procedure SnapFormToMonitorEdgeOnDemand(var X, Y: Integer; AForm: TCustomForm);
var
  DistanceLeft, DistanceRight: Integer;
  CenterMon: TMonitor;
  R: TRect;
begin
  CenterMon := Screen.MonitorFromPoint(
    Point(X + AForm.Width div 2, Screen.DesktopHeight div 2));
  R := CenterMon.WorkareaRect;
  // Adjust X-pos
  DistanceLeft  := X - R.Left;
  DistanceRight := R.Right - (X + AForm.Width);(*
  application.MessageBox(pchar(format('l:%d; r:%d; WRL:%d; WRT:%d; WRR:%d; WRB:%d; x:%d; y:%d', [
    distanceleft, distanceright, r.Left, r.top, r.Right, r.Bottom, x, y])), 'test');*)
  if ((DistanceLeft < 0) and (DistanceRight < 0)) then
  begin
    if DistanceLeft >= DistanceRight then
         X := R.Left // Snap to left edge
    else X := R.Right - AForm.Width; // Snap to right edge
  end
  else if ((DistanceLeft < 0) or (DistanceRight < 0)) then
  begin
    if DistanceLeft < 0 then
         X := R.Left // Snap to left edge
    else X := R.Right - AForm.Width; // Snap to right edge
  end;
  // Adjust Y-pos
  if Y < R.Top then
    Y := R.Top
  else if Y > R.Bottom - AForm.Height then
    Y := R.Bottom - AForm.Height;
//  application.MessageBox(pchar(format('x:%d; y:%d', [x, y])), 'test');
end;
{$ENDIF}

procedure TCustomForm.CMShowingChanged(var Message: TMessage);

// ...

        if (FPosition = poScreenCenter) or
           ((FPosition = poMainFormCenter) and (FormStyle = fsMDIChild)) then
        begin
          if FormStyle = fsMDIChild then
          begin
            X := (Application.MainForm.ClientWidth - Width) div 2;
            Y := (Application.MainForm.ClientHeight - Height) div 2;
          end else
          begin
          {$IFDEF FIXUP_FORM_POPUP_POSITION}
            CenterFormToPrimaryMonitorCenter(X, Y, Self);
          {$ELSE}
            X := (Screen.Width - Width) div 2;
            Y := (Screen.Height - Height) div 2;
          {$ENDIF}
          end;
        {$IFDEF FIXUP_FORM_POPUP_POSITION}
          SnapFormToMonitorEdgeOnDemand(X, Y, Self);
          SetBounds(X, Y, Width, Height);
          //SetWindowToMonitor() will cause unexpected popup position change!
        {$ELSE}
          if X < Screen.DesktopLeft then
            X := Screen.DesktopLeft;
          if Y < Screen.DesktopTop then
            Y := Screen.DesktopTop;
          SetBounds(X, Y, Width, Height);
          if Visible then SetWindowToMonitor;
        {$ENDIF}
        end
        else if FPosition in [poMainFormCenter, poOwnerFormCenter] then
        begin
          CenterForm := Application.MainForm;
          if (FPosition = poOwnerFormCenter) and (Owner is TCustomForm) then
            CenterForm := TCustomForm(Owner);
          if Assigned(CenterForm) then
          begin
            X := ((CenterForm.Width - Width) div 2) + CenterForm.Left;
            Y := ((CenterForm.Height - Height) div 2) + CenterForm.Top;
          end else
          begin
          {$IFDEF FIXUP_FORM_POPUP_POSITION}
            CenterFormToPrimaryMonitorCenter(X, Y, Self);
          {$ELSE}
            X := (Screen.Width - Width) div 2;
            Y := (Screen.Height - Height) div 2;
          {$ENDIF}
          end;
        {$IFDEF FIXUP_FORM_POPUP_POSITION}
          SnapFormToMonitorEdgeOnDemand(X, Y, Self);
          SetBounds(X, Y, Width, Height);
          //SetWindowToMonitor() will cause unexpected popup position change!
        {$ELSE}
          if X < Screen.DesktopLeft then
            X := Screen.DesktopLeft;
          if Y < Screen.DesktopTop then
            Y := Screen.DesktopTop;
          SetBounds(X, Y, Width, Height);
          if Visible then SetWindowToMonitor;
        {$ENDIF}
        end
        else if FPosition = poDesktopCenter then

// ...

end;
Attachment
None
Comments

Markus Humm at 4/28/2008 11:17:46 PM -
Marked as "needs attention"

Server Response from: CODE1