Form WindowState and Position interaction issue

wipnav
wipnav used Ask the Experts™
on
Hi,

I have a simple test program with two forms (the main form is one of them).  Both forms have BorderStyle set to bsSizeable so that I can resize them. The main form has a button to open the second form, attached to this code:

  Form2.WindowState := wsNormal;
  Form2.Top := 100;
  Form2.Left := 100;
  Form2.ShowModal;

If I press the button to show Form2, move it to another position on the screen and close it, the next time I press the button, it opens at (100, 100), which is correct. If after moving it, I maximize it, then close it, the next time I press the button, it does not open at (100, 100). It opens at the location I had moved it to last time it was open.

My question is, how can I get it to always open at (100, 100), even if it was maximized the previous time it was opened?

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.WindowState := wsNormal;
  Form2.Top := 100;
  Form2.Left := 100;
  Form2.ShowModal;
end;

end.

_______________________________________________________________________________________
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

end.

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
in the onShow event of your second form, you can re-set the position to 100,100
Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
in fact, in your case, I would set the WindowsState as well in the onShow
procedure TForm2.FormShow(Sender: TObject);
begin
 WindowState := wsNormal;
 Top := 100;
 Left := 100;
end;

Open in new window

Author

Commented:
Did that work for you? What version of Delphi do you have? I have 2006, and that doesn't work.
Fundamentals of JavaScript

Learn the fundamentals of the popular programming language JavaScript so that you can explore the realm of web development.

Hmm, that is odd. I totally reproduced your issue on my system WinXP and D2007. It seems when you when you close Form2 from Maximized the form then sets it’s location after it’s OnShow and OnActivate events. I was able to work around it with the code below though I feel that this is a bit of a hack. Nonetheless you could use this hack to accomplish your goal.
procedure TForm2.FormShow(Sender: TObject);
begin
     tmrOpen.Interval := 10;
     tmrOpen.Enabled := True;
end;

procedure TForm2.tmrOpenTimer(Sender: TObject);
begin
     tmrOpen.Enabled := False;
     WindowState := wsNormal;
     Top := 100;
     Left := 100;
end;

Open in new window

I should mention, just for clarity, that I added a TTimer component named tmrOpen to Form2

Author

Commented:
I'm all for a good hack, but the timer is a bit much, even for me.

I wonder if there is something that can be done after the form is closed to set the window state back to normal?
Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
> Did that work for you? What version of Delphi do you have? I have 2006, and that doesn't work.
I hadn't tried first but now yes, it totally works for me on D2007/ Vista64.
Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
still, I have many issues of windows positions when using D2007 under Vista 64 (I might add that a few app that are not my own have similar issues, even MS explorer) with the windows stuck in the top/left corner with a stupid size of 320x240 when first launched. I can workaround this only by stating the form Position to poDefault (which is straight stupid and contradictory with Position definition in help). I suppose this is a Vista bug.

You might want to try playing with the Position property as well to see if something is changing
Commented:
Adding a call to SetWindowPlacement in TForm2.FormShow fixes the problem.

procedure TForm2.FormShow(Sender: TObject);
var
  Placement: TWindowPlacement;
begin
  Placement.Length := SizeOf(TWindowPlacement);
  with Placement do
  begin
    Flags := 0;
    ShowCmd := sw_ShowNormal;
    ptMinPosition.X := 0;
    ptMinPosition.Y := 0;
    ptMaxPosition.X := 0;
    ptMaxPosition.Y := 0;
    rcNormalPosition.Left := Left;
    rcNormalPosition.Top := Top;
    rcNormalPosition.Right := Pred(rcNormalPosition.Left + Width);
    rcNormalPosition.Bottom := Pred(rcNormalPosition.Top + Height);
  end;
  SetWindowPlacement(Handle, @Placement);
end;
Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
that's an incredibly big hammer to smash a fly, but as long as it works for you...
I'm curious about the reason why such a basic feature of Delphi forms is not working on your application. I guess we'll never know :o/

Author

Commented:
It's interesting that SteveBay saw the problem on WinXP/D2007, but you didn't on Vista64/D2007. Maybe it's an XP problem.
Mike McCrackenSenior Consultant
Most Valuable Expert 2011
Top Expert 2013

Commented:
This question has been classified as abandoned and is being closed as part of the Cleanup Program.  See my comment at the end of the question for more details.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial