Setting a form to WindowState = wsMaximized
will sometimes cause the form to be maximized but not:
Long-time bug: this is a question I first asked in the Borland newsgroups in 2003:
and then again in 2006:
and then again in 2008:
Someone asked it on the Embarcadero forums in 2012:
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:
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:
- Create a new app and a form.
- Set the form to maximized (WindowState = wsMaximized) at design time.
- Drop a ListView control on the form
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;
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With