我正在Delphi写一个屏幕保护程序。我想要在每台显示器上全屏显示一个TpresentationFrm。为此,我写了下面的(不完全)程序:如何在辅助监视器上显示表单?
program ScrTemplate;
uses
...
{$R *.res}
type
TScreenSaverMode = (ssmConfig, ssmDisplay, ssmPreview, ssmPassword);
function GetScreenSaverMode: TScreenSaverMode;
begin
// Some non-interesting code
end;
var
i: integer;
presentationForms: array of TpresentationFrm;
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
case GetScreenSaverMode of
ssmConfig:
Application.CreateForm(TconfigFrm, configFrm);
ssmDisplay:
begin
SetLength(presentationForms, Screen.MonitorCount);
for i := 0 to high(presentationForms) do
begin
Application.CreateForm(TpresentationFrm, presentationForms[i]);
presentationForms[i].BoundsRect := Screen.Monitors[i].BoundsRect;
presentationForms[i].Visible := true;
end;
end
else
ShowMessage(GetEnumName(TypeInfo(TScreenSaverMode), integer(GetScreenSaverMode)));
end;
Application.Run;
end.
当执行ssmDisplay
码,两种形式确实是创造了(是的,我有整整两个显示器)。但它们都出现在第一台显示器上(索引0,但不是主要显示器)。
当单步调试代码,我看到Screen.Monitors[i].BoundsRect
是正确的,但由于某些原因的形式得到不正确的边界:
Watch Name Value (TRect: Left, Top, Right, Bottom, ...)
Screen.Monitors[0].BoundsRect (-1680, 0, 0, 1050, (-1680, 0), (0, 1050))
Screen.Monitors[1].BoundsRect (0, 0, 1920, 1080, (0, 0), (1920, 1080))
presentationForms[0].BoundsRect (-1680, 0, 0, 1050, (-1680, 0), (0, 1050))
presentationForms[1].BoundsRect (-1920, -30, 0, 1050, (-1920, -30), (0, 1050))
第一种形式得到所需的位置,但第二次却没有。它不是从x = 0到1920,而是占用x = -1920到0,即它出现在第一个监视器上,高于第一个表格。哪里不对?什么是正确的程序来完成我想要的?
您将有高DPI显示器的问题,如果您的应用程序不包含在其清单的highdpi意识到标志。在这种情况下,Windows将报告一个错误的(虚拟)绑定矩形。 – Ampere 2017-12-14 13:16:16