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 anEdit
on a form:Add an
OnEnter
event for theTEdit
:procedure TForm1.Edit1Enter(Sender: TObject); begin Label1.Font.Style := Label1.Font.Style + [fsBold]; end;
and set the form:
WindowState
to wsMaximizedAutoScroll
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.
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.