Home > Net >  Show a form on bottom right position of the screen
Show a form on bottom right position of the screen

Time:08-24

I noticed a strange issue in a Delphi 11.1 Windows application.

I need to show Form3 on the bottom right of the screen after 5 minutes a button is clicked:

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  Timer2.Enabled := False;
        
  // Set form position on bottom right of the screen
  with Form3 do
  begin
  Top := Screen.Height - Form3.Height - GetTaskBar_Y_Bottom_Height();
  Left := Screen.Width - Form3.Width - GetTaskBar_X_Right_Width();
  end;
 
  // Now show the form
  Form3.Show;
end;
    
procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer2.Enabled := True;
end;

Here is a screenshot:

enter image description here

It works fine and the Form3 is shown on the bottom right of the screen... well, most of the time.

Because on some random occasions, it is shown on the top left of the screen:

enter image description here

Even if Screen.Height and Screen.Width are correct:

Screen.Height = 1080
Screen.Width = 1920

Why on some occasions (generally on the first time I try) it is shown on top left?

Do you have any idea what can be?

Some other details:

  • I am using a single monitor with 1920 x 1080 resolution.
  • The manifest of the application uses the high-DPI aware option "Per Monitor v2".

//Edit

If I compile the same code with Delphi Tokyo 10.2 the issue seems gone, if I compile it with Delphi 11.1 the issue appears randomly and generally on the first time I click the Button1, from the second time and up it is always on bottom right.

CodePudding user response:

As you did not yet respond to my request for the GetTaskBar... functions, we can just ditch them and use a better method to assess the available work area.

Also, you do not account for the position of the taskbar. Many, if not most, users let it stay on the bottom, but users may prefer to keep it at left, at top or at right edge of the monitor.

To account for the different layouts, you can use something like this OnShow event of Form3:

procedure TForm3.FormShow(Sender: TObject);
begin
  Left := Screen.WorkAreaRect.Right - Width;
  Top := Screen.WorkAreaRect.Bottom - Height;
end;

And you would call it from the timer event in Form1

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  Timer2.Enabled := False;
  Form3.Show;
end;
  • Related