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
コードが実行されると、実際に 2 つのフォームが作成されます (はい、ちょうど 2 つのモニターがあります) 。ただし、両方とも最初のモニターに表示されます (インデックス 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))
最初のフォームは目的の位置を取得しますが、2 番目のフォームは取得しません。x=0 から 1920 に移動する代わりに、x=-1920 から 0 を占有します。つまり、最初のモニターの最初のフォームの上に表示されます。なにが問題ですか?私が望むものを達成するための適切な手順は何ですか?