a Delphi form does incorrect behavior, when maximizing the form (even in IDE designer), why?

95 Views Asked by At

This is a cut-down version from a full Delphi Application. Even in the Delphi7 IDE designer, when double-clicking on the form's caption, the form maximizes incorrectly, which means that the top left corner will move to Screen coordinate (0,0), but the form does not really maximize.

Here are attached the two relevant files: FaultyFormF.pas FaultyFormF.dfm

unit FaultyFormF;
{$O-}
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;

type
  TfrmFaultyForm = class(TForm)
    pnlControl: TPanel;
    pnlDataContainer: TPanel;
    lbl_pnlDataContainer_Left: TLabel;
  private
    { Private declarations }

  public
    { Public declarations }

  end;

var
  frmFaultyForm: TfrmFaultyForm;

implementation

uses Types;

{$R *.dfm}

end.

Then the DFM file FaultyFormF.dfm:

object frmFaultyForm: TfrmFaultyForm
  Left = 277
  Top = 133
  Width = 899
  Height = 497
  AutoSize = True
  Caption = 'FaultyForm'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  DesignSize = (
    891
    470)
  PixelsPerInch = 96
  TextHeight = 13
  object lbl_pnlDataContainer_Left: TLabel
    Left = 200
    Top = 0
    Width = 153
    Height = 8
    Alignment = taCenter
    AutoSize = False
    Caption = 'lbl_pnlDataContainerLeft'
    Color = clLime
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentColor = False
    ParentFont = False
    Visible = False
  end
  object pnlControl: TPanel
    Left = 0
    Top = 12
    Width = 185
    Height = 458
    Anchors = [akLeft, akTop, akBottom]
    TabOrder = 0
  end
  object pnlDataContainer: TPanel
    Left = 200
    Top = 12
    Width = 691
    Height = 458
    Anchors = [akLeft, akTop, akRight, akBottom]
    TabOrder = 1
  end
end

I formerly used the Constraints:TSizeConstraints property in Delphi IDE's Object Inspector to set a MinWidth value, but I removed that because I suspected it may have something with the observed incorrect maximizing behavior of this form. After removing that, I checked by using Delphi's "View as Text" local menu option in the form designer, and found, that Delphi had correctly removed all the Constraints -lines from the text-form DFM data.

So it seems that the suspection of the Constraints to have something to do with the problem is likely wrong.

Since I removed also any and all OnResize -event handlers, they should have nothing to do with the incorrect maximizing behavior, either - and unless one installs his own components to the Delphi IDE (which I have not done), such OnResize -event handlers are relevant only to the runtime behavior of a Delphi app, NOT how it behaves in the Delphi IDE form designer.

In Delphi7's Form designer, double-clicking the Form's Caption twice to first maximize the form - and then restore it to normal size again - is a good way to verify that one has set the Anchors property of all visible components correctly.

Unfortunately, in newer versions of Delphi, double-clicking the Form's Caption no longer maximizes the form, making running the application the only way to verify, that one has set the Anchors property of all visible components correctly.

Or is there some trick to maximize a form at design time in newer versions of Delphi, that I am not aware of?

Added screenshot, that shows, that a round trip: Maximized -> normal -> Maximized will decrease the height of the Maximized window by 24 pixels per each round trip:

Repeat: "Restored to Normal -> Maximized" 3 times after first time maximized.

Log memo line format: HH:MM:SS.cc Width x Height WindowState, where cc = 1/100 s units. The first line was produced from the FormCreate() -event handler.

Here is the updated example form, first the PAS file:

unit FaultyFormF;
{$O-}
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;

type
  TfrmFaultyForm = class(TForm)
    pnlControl: TPanel;
    pnlDataContainer: TPanel;
    lbl_pnlDataContainer_Left: TLabel;
    pnlInfoScreen: TPanel;
    pnlInfoForm: TPanel;
    Label1: TLabel;
    lblScreenWidth: TLabel;
    lblScreenHeight: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label2: TLabel;
    lblFormWidth: TLabel;
    lblFormHeight: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    memLog: TMemo;
    procedure FormResize(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }

  public
    { Public declarations }

  end;

var
  frmFaultyForm: TfrmFaultyForm;

implementation

uses Types;

{$R *.dfm}

const
  WindowStateNames : Array[TWindowState] of String = ('wsNormal', 'wsMinimized', 'wsMaximized');

function TimeStr:String;
begin
  Result := FormatDateTime('hh:nn:ss.zzz', Now);
  Result[Length(Result)] := ' ';  // remove the 3rd decimal of seconds - leave only 1/100th of a second as the smallest time unit.
end;

procedure TfrmFaultyForm.FormResize(Sender: TObject);
begin
  // Form Resize:
  lblScreenWidth.Caption  := IntToStr(Screen.Width);
  lblScreenHeight.Caption := IntToStr(Screen.Height);
  lblFormWidth.Caption    := IntToStr(Width);
  lblFormHeight.Caption   := IntToStr(Height);

  // Add Form Size Info Line:
  memLog.Lines.Add( TimeStr + IntToStr(Width) + 'x' + IntToStr(Height) + ' ' + WindowStateNames[WindowState] );
end;

procedure TfrmFaultyForm.FormCreate(Sender: TObject);
begin
  memLog.Lines.Add( TimeStr + IntToStr(Width) + 'x' + IntToStr(Height) + ' ' + WindowStateNames[WindowState] + ' FormCreate()' );
end;

end.

Here is the updated DFM file:

object frmFaultyForm: TfrmFaultyForm
  Left = 277
  Top = 133
  Width = 899
  Height = 497
  AutoSize = True
  Caption = 'FaultyForm'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnResize = FormResize
  DesignSize = (
    891
    470)
  PixelsPerInch = 96
  TextHeight = 13
  object lbl_pnlDataContainer_Left: TLabel
    Left = 200
    Top = 0
    Width = 153
    Height = 8
    Alignment = taCenter
    AutoSize = False
    Caption = 'lbl_pnlDataContainerLeft'
    Color = clLime
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentColor = False
    ParentFont = False
    Visible = False
  end
  object pnlControl: TPanel
    Left = 0
    Top = 12
    Width = 185
    Height = 458
    Anchors = [akLeft, akTop, akBottom]
    TabOrder = 0
  end
  object pnlDataContainer: TPanel
    Left = 200
    Top = 12
    Width = 691
    Height = 458
    Anchors = [akLeft, akTop, akRight, akBottom]
    TabOrder = 1
    object pnlInfoScreen: TPanel
      Left = 16
      Top = 16
      Width = 201
      Height = 161
      TabOrder = 0
      object Label1: TLabel
        Left = 8
        Top = 8
        Width = 37
        Height = 13
        Caption = 'Screen:'
      end
      object lblScreenWidth: TLabel
        Left = 104
        Top = 28
        Width = 72
        Height = 13
        Caption = 'lblScreenWidth'
      end
      object lblScreenHeight: TLabel
        Left = 104
        Top = 48
        Width = 75
        Height = 13
        Caption = 'lblScreenHeight'
      end
      object Label4: TLabel
        Left = 8
        Top = 28
        Width = 31
        Height = 13
        Caption = 'Width:'
      end
      object Label5: TLabel
        Left = 8
        Top = 48
        Width = 34
        Height = 13
        Caption = 'Height:'
      end
    end
    object pnlInfoForm: TPanel
      Left = 16
      Top = 192
      Width = 201
      Height = 161
      TabOrder = 1
      object Label2: TLabel
        Left = 8
        Top = 8
        Width = 26
        Height = 13
        Caption = 'Form:'
      end
      object lblFormWidth: TLabel
        Left = 104
        Top = 28
        Width = 61
        Height = 13
        Caption = 'lblFormWidth'
      end
      object lblFormHeight: TLabel
        Left = 104
        Top = 48
        Width = 64
        Height = 13
        Caption = 'lblFormHeight'
      end
      object Label7: TLabel
        Left = 8
        Top = 28
        Width = 31
        Height = 13
        Caption = 'Width:'
      end
      object Label8: TLabel
        Left = 8
        Top = 48
        Width = 34
        Height = 13
        Caption = 'Height:'
      end
    end
    object memLog: TMemo
      Left = 240
      Top = 8
      Width = 441
      Height = 345
      ScrollBars = ssVertical
      TabOrder = 2
      WordWrap = False
    end
  end
end

UPDATED question:

  1. Added a screenshot

  2. Added a modified version of both the PAS and the DFM file.

Screen size: 1600 x 900 pixels. Windows OS display scaling is not used.

And, other Delphi forms behave correctly (other than the original faulty one of which this is a simplified, cut-down version).

1

There are 1 best solutions below

2
Ian Boyd On

Using your code I was able to reproduce the problem.

You are running into a well-known, decades old, "Won't Fix" bug in Delphi. The workaround is to set the Form.AutoSize property to False at design time:

Delphi designer showing form and properties

This then lets the form be maximized correctly both at runtime and design time: Form maximizes correctly at runtime

I'm guessing the arm-chair commenters are running at standard DPI.