Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wsMaximized forms do not appear maximized

Setting a form to WindowState = wsMaximized will sometimes cause the form to be maximized but not:

enter image description here

Long-time bug: this is a question I first asked in the Borland newsgroups in 2003:

  • Accepted fix for WindowState = wsMaximized?

and then again in 2006:

  • wsMaximized breaks it, NOT caused by Position=poScreenCenter, reproducible dfm

and then again in 2008:

  • Forms not starting maximized

Someone asked it on the Embarcadero forums in 2012:

  • Thread: Application not starting with maximized window

Now it's time to port the 18 year old bug to Stackoverflow. Maybe someone's finally figured out a workaround.

Steps to reproduce:

My posts contained half a dozen failure modes, but the easiest is:

  • Drop a Label and an Edit on a form:

    enter image description here

  • Add an OnEnter event for the TEdit:

    procedure TForm1.Edit1Enter(Sender: TObject); begin    Label1.Font.Style := Label1.Font.Style + [fsBold]; end; 
  • and set the form:

    • WindowState to wsMaximized
    • AutoScroll to False

And bazinga, fails.

One of the other set of steps from the 2008 post:

  1. Create a new app and a form.
  2. Set the form to maximized (WindowState = wsMaximized) at design time.
  3. Drop a ListView control on the form
  4. During OnShow, add 20 empty items to the list view:

    procedure TForm1.FormShow(Sender: TObject); var      i: Integer; begin      for i := 1 to 20 do           ListView1.Items.Add;  end; 
  5. Set the form's AutoScroll property to false (AutoScroll = False) at design time

Of course what I'm not after is "fixed in version n of RadStudio. Just use that". I'm looking for an actual fix (if there is one); which could include quoting relevant changes to the VCL source when CodeGear finally did fix it. (If it is even fixed).

Note: Changing Position from poDesigned to anything else doesn't fix it.

Workaround

A horrible, ugly, awful, disgusting, workaround I had been using was to start a timer during OnShow, and then when the timer fires, maximize the form:

procedure TForm1.tmrVclMaximizeHackTimer(Sender: TObject); begin    Self.WindowState := wsMaximized; end; 

I later improved this hack to post a message during OnShow; which is essentially the same as a timer message, without having to use a timer:

const   WM_MaximizeWindow = WM_APP + $03;  procedure TForm1.FormShow(Sender: TObject); begin   if (Self.WindowState = wsMaximized) then   begin      Self.WindowState := wsNormal;      PostMessage(Self.Handle, WM_MaximizeWindow , 0, 0);   end; end;  private    procedure WMMaximizeWindow(var Message: TMessage); message WM_MaximizeWindow;  procedure TForm1.WMMaximizeWindow(var Message: TMessage); begin    Self.WindowState := wsMaximized; end; 

Sometimes I invent the OnAfterShow event that Delphi never did:

const   WM_AfterShow = WM_APP + $02;  procedure TForm1.FormShow(Sender: TObject); begin   PostMessage(Self.Handle, WM_AfterShow, 0, 0);   if (Self.WindowState = wsMaximized) then   begin      Self.WindowState := wsNormal;      FMaximizeNeeded := True;   end; end;  private    procedure WMAfterShow(var Message: TMessage); message WM_AfterShow;  procedure TForm1.WMAfterShow(var Message: TMessage); begin    if FMaximizeNeeded then    begin           FMaximizeNeeded := False;       Self.WindowState := wsMaximized;    end; end; 

But no hacks are better than hacks.

like image 794
Ian Boyd Avatar asked Oct 20 '13 17:10

Ian Boyd


1 Answers

I Can reproduce with D7/Win7.

I don't use wsMaximized at all (similar random problems as you describe).

Workaround: use OnActivate -> ShowWindow(Handle, SW_MAXIMIZE) e.g.:

procedure TForm1.FormActivate(Sender: TObject); begin   // Maximize only once when the Form is first activated   if not FMaxsimized then   begin     FMaxsimized := True;     ShowWindow(Handle, SW_MAXIMIZE);   end; end; 

This method will not work during OnShow.

Better Workaround: use ShowWindowAsync during OnShow or OnCreate e.g:

procedure TForm1.FormCreate(Sender: TObject); begin   ShowWindowAsync(Handle, SW_MAXIMIZE); end; 

This sets the show state of a window without waiting for the operation to complete.

like image 167
kobik Avatar answered Sep 30 '22 16:09

kobik