3

I have an application which always starts initially maximized. This consists of putting Self.WindowState := wsMaximized; in the OnCreate of the main form.

Just before that, I'm assigning what should be the default dimensions of the main form, if the user were to change the window state to wsNormal.

So, in short, the main form's OnCreate handler looks something like:

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  Width:= 1300;
  Height:= 800;
  WindowState:= wsMaximized;
end;

Theoretically, I could assign these dimensions in design-time, and that does what I need. However, due to the size of my screen, and thus the IDE, the whole form is not visible at one glance without scrolling. In design, I keep the form size small, so I can see everything. But in runtime, I need to assign these default dimensions, and then maximize it by default. When the user changes the window state out of maximized, I expect it to go to those dimensions I dynamically assigned.

The issue is that it seems to lose those dimensions after maximizing the form, and it reverts back to whatever values were in design-time. If I comment out the line WindowState:= wsMaximized; then it shows the form in the desired default dimensions. However, maximizing it seems to overwrite and ignore these values I had just assigned before it.

How can I create and show my main form maximized by default, while at the same time dynamically assigning the default size, without my assigned values getting lost?

Jerry Dodge
  • 25,720
  • 28
  • 139
  • 301
  • Can you reproduce this with a blank project? – Sertac Akyuz Jun 27 '20 at 00:32
  • I suspect you have wsMaximized in the designer, leave it at wsNormal. – Sertac Akyuz Jun 27 '20 at 00:33
  • @SertacAkyuz It is untouched at `wsNormal`. – Jerry Dodge Jun 27 '20 at 00:58
  • 2
    Looks like a case for SetWindowPlacement, but can't tell for sure since I don't have a repro. – Sertac Akyuz Jun 27 '20 at 02:52
  • @JerryDodge: What Delphi version are you using? In 10.3.2, I cannot reproduce this issue. (Yet it feels vaguely familiar.) – Andreas Rejbrand Jun 27 '20 at 08:08
  • What is the value of OldCreateOrder in your dfm file? – David Heffernan Jun 27 '20 at 08:14
  • 1
    I agree with Sertac. This feels like something `SetWindowPlacement()` can be used for, without having to change the Form's `Width`/`Height` properties. – Remy Lebeau Jun 27 '20 at 10:53
  • 1
    Not meaning to be difficult @JerryDodge, but I think this q should really have a full [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) including Delphi & OS version, etc. – MartynA Jun 27 '20 at 16:30
  • I cannot reproduce it with Delphi 10.1 either. – Uwe Raabe Jun 27 '20 at 21:01
  • 1
    Not sure how much more clear I can make it. Added Delphi and Windows version tags. But that's all the code necessary to reproduce it in my environment. At least one or two people were able to reproduce this issue too. Odd how it happens only in some environments. – Jerry Dodge Jun 28 '20 at 00:27
  • @David It's a new form, and I haven't touched this value. It's currently set to `False`. – Jerry Dodge Jun 28 '20 at 00:28
  • Based on the random trend of this issue, I would have to blame Windows and some specific unknown settings which are throwing this off. Might have to do with the newer window actions such as dragging to an edge of the screen to maximize or enable split view. – Jerry Dodge Jun 28 '20 at 00:31
  • I definitely think a [mcve] would be helpful here. – David Heffernan Jun 28 '20 at 07:40
  • 2
    @David As mentioned, the above code is all that's needed to reproduce it in my environment. New VCL forms application, add an `OnCreate` handler for the main form, and put those 3 lines of code. – Jerry Dodge Jun 28 '20 at 14:16

3 Answers3

5

(Confirmed with 10.3.3.) The exact origin of this problem I cannot pinpoint, but a reasonable cause would be that during the constructor the form component is being read and that previous sizes seem to be explicitly backed up:

procedure TControl.SetWidth(Value: Integer);
begin
  SetBounds(FLeft, FTop, Value, FHeight);
  Include(FScalingFlags, sfWidth);
  if csReading in ComponentState then
    FExplicitWidth := FWidth;
end;

A possible solution is to set the desired sizes in the OnCreate event, like you are doing now, but postpone setting the desired WindowsState until the OnShow event.

procedure TForm1.FormCreate(Sender: TObject);
begin
  Width := 1300;
  Height := 800;
end;

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

Of course, you probably should prevent consecutive calls by using a one-off mechanism. Please take a look at wsMaximized forms do not appear maximized too.

NGLN
  • 41,230
  • 8
  • 102
  • 186
3

Apparently, the VCL does not store the explicit intermediate size (in some Delphi versions anyway) but seems to merge the change with that of the maximization when the form is actually shown.

Like Sertac Akyuz quite correctly suggested, you can use SetWindowPlacement to bypass this VCL interference:

procedure TForm1.FormCreate(Sender: TObject);
var
  WindowPlacement: TWindowPlacement;
begin
  GetWindowPlacement(Handle, WindowPlacement);
  WindowPlacement.rcNormalPosition := Bounds(Left, Top, 1300, 800);
  WindowPlacement.showCmd := SW_SHOWMAXIMIZED;
  SetWindowPlacement(Handle, WindowPlacement);
end;
NGLN
  • 41,230
  • 8
  • 102
  • 186
1

You must set form size on FormActivate:

procedure TfrmMain.FormActivate(Sender: TObject);
begin
  if Tag = 0 then
  begin
    // Top := 100;
    // Left := 100;
    Width:= 1300;
    Height:= 800;
    WindowState:= wsMaximized;
    Tag := 1;
  end;
end;
Branko
  • 1,299
  • 1
  • 15
  • 31
  • This will cause a brief flickering, since the initial position and size will be visible before this code is executed. (And I don't quite know what problem this approach is trying to solve, since I can't reproduce the OP's issue. `FormCreate` works for me.) – Andreas Rejbrand Jun 27 '20 at 08:05
  • @AndreasRejbrand: I also use Delphi 10.3.2 (Win 10) and it doesn't work with OnCreate so I use OnActivate. And yes, there is brief flickering :( – Branko Jun 27 '20 at 08:27
  • I have the same problem, Delphi 10.3.3. The answer solves it, but there is flickering and some ugly black boxes briefly are visible. I have solved this for the time being by starting the form minimized, then posting a message that activates it. In this case Windowstate must be set to wsNormal first and then to wsMaximized, otherwise the size still doesn't stick. – Renate Schaaf Jun 27 '20 at 08:44