我正在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