I am writing a screensaver in Delphi. I want to show TpresentationFrm on each monitor, in full screen mode. To this end, I wrote the following (incomplete) program:
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.
When the ssmDisplay code is ssmDisplay , two forms are really created (yes, I have exactly two monitors). But they both appear on the first monitor (index 0, but not the main one).
When navigating through the code, I see that Screen.Monitors[i].BoundsRect are correct, but for some reason the forms get the wrong borders:
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))
The first form gets the desired position, and the second does not. Instead of moving from x = 0 to 1920, it takes from x = -1920 to 0, that is, it appears on the first monitor above the first form. What's wrong? What is the proper procedure for doing what I want?