Я пишу экранную заставку в 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, т.е. это появляется на первом мониторе выше первой формы. Что не так? Что надлежащая процедура должна выполнить то, что я хочу?
Форма должна быть видимой, чтобы установить границы с помощью BoundRect.
Переверните строки следующим образом:
presentationForms[i].Visible := true;
presentationForms[i].BoundsRect := Screen.Monitors[i].BoundsRect;
Видимо пытаюсь поставить позицию преждевременно.
Замените для блока цикла
на
Application.CreateForm(TpresentationFrm, presentationForms[i]);
presentationForms[i].Tag := i;
presentationForms[i].Visible := true;
, а затем напишите
procedure TpresentationFrm.FormShow(Sender: TObject);
begin
BoundsRect := Screen.Monitors[Tag].BoundsRect;
end;