20
votes

Is there a way to specify which monitor a application appears on in Delphi or C++Builder?

I am developing a simple program for a customer, which displays kitchen orders on a secondary monitor, generated by a hospitality system. Currently they need to manually drag the window onto the second monitor after it starts.

7

7 Answers

28
votes

The global Screen object (part of Forms) has the concept of Monitors. I think this was added circa Delphi 6 or 7. The following code will work:

// Put the form in the upper left corner of the 2nd monitor
//   if more then one monitor is present.
if Screen.MonitorCount > 1 then
begin
  Left := Screen.Monitors[1].Left;
  Top := Screen.Monitors[1].Top;
end;

You could use any positive offset from that position to put it anywhere in that monitor. You can get the width and height from there too to know the dimensions.

23
votes

Save the window position before program shutdown and restore them on startup. Multimonitor displays just increase the size of the desktop; other monitor surfaces just have a different section of the same X/Y plane with its origin at the top-left of the primary monitor.

This can be done automatically for you by any of several components.

BTW, the Screen variable in the Forms unit has a property called MonitorCount and another indexable property, Monitors[Index: Integer]: TMonitor. TMonitor has properties indicating the left, top, width, height etc., so all the information you need is there.

2
votes
procedure TMDIChild.btnShowMonClick(Sender: TObject);
begin
    if Screen.MonitorCount > 1 then
    begin
      FormShow.Left:=Screen.Monitors[1].Left;
      FormShow.Top:=Screen.Monitors[1].Top;
      FormShow.Width:=Screen.Monitors[1].Width;
      FormShow.Height:=Screen.Monitors[1].Height;
    end
    else
    begin
        FormShow.Show;
    end;
end;
1
votes

Not really the answer your question implies, but couldn't you store the window settings (size, position, Maximized State) when ever the application is closed, and then apply them at startup?

-2
votes

I have done a similar thing a while ago in Delphi 5:

procedure TForm18.FormCreate(Sender: TObject);
var
  Mon: TMonitor;
  MonitorIdx: Integer;
begin
  MonitorIdx := 1; // better read from configuration
  if (MonitorIdx <> Monitor.MonitorNum) and (MonitorIdx < Screen.MonitorCount) then begin
    Mon := Screen.Monitors[MonitorIdx];
    Left := Left + Mon.Left - Monitor.Left;
    Top := Top + Mon.Top - Monitor.Top;
  end;
end;
-3
votes

Windows will let you specify the coordinates of a window in the CreateWindow API call. I don't know enough about Delphi or C++Builder to know if you have access to that part of the process.

You might also be able to move the window in a WM_CREATE handler.

EnumDisplayMonitors will give you the coordinates of each monitor in the system.


-6
votes

I don't do much with windows systems, so I would suggest a hack like this.

Grab the width of the viewable desktop(both monitors combined), divide it by half and make that your starting position.

You may also look into what api tells you monitor2's dimensions.