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:
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:
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;