Take control of Delphi forms in your multimonitor application

The authors of the the VCL helpfully added multi monitor “support” a few versions back. Somewhat less helpfully, this support is very limited – it has no way to say “create form X on monitor 3”, which is a very useful thing to do in some kinds of applications – those intended to run on a multimon system in a specific configuration.

You can readily move forms around (with .Left, .Top, etc.) on to specific monitors after a Form is open, but not while it is opening (in OnShow or OnCreate), because a fine method TCustomForm.SetWindowToMonitor will jump in and undo your work.

Not surprisingly, most of the obvious methods to override to fix this, are not virtual. (An aside – I think the bias toward final methods in Delphi, C#, and some other languages, is a poor idea, and I think the guideline of “design for overriding, or prevent it” is even worse.) With some looking, I found a workaround, shown here somewhat mangled by WordPress:

private

FSetBoundsEnabled: boolean;

public

procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;

…..

procedure TSomeForm.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);

begin if FSetBoundsEnabled then inherited;

end;

FSetBoundsEnabled will be False by default. Sometime after your form is loaded (use a Timer or a windows message to signal this), set FSetBoundsEnabled := True then set your .Left and .Top to put your form whereever it needs to be.

3 thoughts on “Take control of Delphi forms in your multimonitor application”

  1. I realise this is fairly old but being as it’s still published I thought I’d share my experience.

    The way I handle this in D7 is to set the form to be Position=poDefault and then use this code in FormShow

    Self.Top := Screen.Monitors[ScreenNo].Top + ((Screen.Monitors[ScreenNo].Height div 2) – (Self.Height div 2));
    Self.Left := Screen.Monitors[ScreenNo].Left + ((Screen.Monitors[ScreenNo].Width div 2) – (Self.Width div 2));

    Where “ScreenNo” is an integer that is pre-checked in the dpr to make sure it’s valid or it gets set to 0.

Comments are closed.