I'm experiencing a weird issue when I set "DPI Awareness" mode in the project options to "GDI Scaling" with a secondary form, where, if I set its BorderStyle to bsNone and change its position while the Main form is on another monitor with different DPI scaling, the coordinates (within Monitor 1) are completely off. Let me explain my case and how to reproduce more clearly:
My setup (Windows 11)
- Monitor 1: 1920x1080, 100% scale (DPI)
- Monitor 3: 4K TV, cloned with Monitor 1
- Monitor 2: 1920x1200, 150% scale (DPI), to the right of Monitor 1
Case 1: I create Form2 (bsSizeable), Form1 is in either Monitor, I change Form2's position -> OK
Case 2: I create Form2 (bsNone), Form1 is in Monitor 1, I change Form2's position -> OK
Case 3: I create Form2 (bsNone), -move Form1 to Monitor 2-, then change Form2's position -> the position is completely wrong.
"Per Monitor v2" -> OK in all cases (different, unrelated issues, however)
"GDI Scaling" + bsSizeable (Form2) -> OK
"GDI Scaling" + bsNone (Form2) -> wrong position
DPR
program Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2},
Vcl.Themes,
Vcl.Styles;
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Unit 1
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses Unit2;
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Application);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Form2.Left := Screen.PrimaryMonitor.WorkareaRect.Left + 300;
Form2.Top := Screen.PrimaryMonitor.WorkareaRect.Top + 300;
Form1.Caption := Form2.Left.ToString + ' - ' + Form2.Top.ToString;
end;
end.
Form 1
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 312
ClientWidth = 296
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
Position = poScreenCenter
TextHeight = 15
object Button1: TButton
Left = 8
Top = 8
Width = 185
Height = 121
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 8
Top = 135
Width = 185
Height = 114
Caption = 'Button2'
TabOrder = 1
OnClick = Button2Click
end
end
Unit 2
unit Unit2;
interface
uses
Winapi.Windows, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, ShellApi,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm2 = class(TForm)
Label1: TLabel;
private
procedure CreateParams(var Params : TCreateParams); override;
public
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.CreateParams(var Params : TCreateParams);
begin
inherited CreateParams(Params);
With Params do begin
ExStyle := ExStyle or WS_EX_TOPMOST;
WndParent := GetDesktopwindow;
end;
end;
end.
Form 2
object Form2: TForm2
Left = 100
Top = 100
AlphaBlendValue = 200
BorderStyle = bsNone
Caption = 'Form2'
ClientHeight = 95
ClientWidth = 201
Color = 4227327
TransparentColorValue = clGreen
DefaultMonitor = dmPrimary
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
FormStyle = fsStayOnTop
Position = poScreenCenter
Visible = True
TextHeight = 15
object Label1: TLabel
Left = 8
Top = 8
Width = 142
Height = 37
Caption = 'Hello World'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -27
Font.Name = 'Segoe UI'
Font.Style = []
ParentFont = False
end
end