Delphi 11.3:GDI缩放+bsNone边框样式多显示器坐标异常问题
Delphi 11.3中GDI Scaling模式下bsNone二级窗体坐标异常问题
问题概述
在Delphi 11.3项目中,将DPI Awareness模式设置为GDI Scaling时,若二级窗体的BorderStyle设为bsNone,且主窗体位于不同DPI缩放的显示器上,二级窗体在主显示器(Monitor 1)的坐标会完全错误。
设备配置(Windows 11)
- Monitor 1:1920×1080,100%缩放(DPI)
- Monitor 3:4K电视,与Monitor 1克隆显示
- Monitor 2:1920×1200,150%缩放(DPI),位于Monitor 1右侧
测试场景
- Form2设为
bsSizeable,Form1在任意显示器,修改Form2位置→正常 - Form2设为
bsNone,Form1在Monitor 1,修改Form2位置→正常 - Form2设为
bsNone,将Form1移至Monitor 2后修改Form2位置→坐标完全错误
其他模式验证
- Per Monitor v2模式下所有情况正常(存在其他无关问题)
- GDI Scaling+Form2为
bsSizeable→正常 - GDI Scaling+Form2为
bsNone→坐标错误
复现代码
Project1.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.
Unit1.pas
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.
Form1.dfm
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
Unit2.pas
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.
Form2.dfm
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
内容的提问来源于stack exchange,提问作者hikari
相关产品推荐
相关产品推荐

