views:

6031

answers:

6

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.

A: 

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.

J.J.
That would only work if both monitors have the same size desktop.
Re0sless
@ReOsless: Ya. Like I said it's a hack.
J.J.
A: 

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.


Evidently Delphi and C++ Builder have facilities that make this answer somewhat irrelevant. I'll leave it here in case someone comes across this question but needs it answered for a different environment.

Mark Ransom
Delphi has abstractions to cover all these functions, from Screen.Monitors collection through to pre-construction events for controlling form position.
Barry Kelly
+1  A: 

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?

Nathen Silver
This is the simplest implementation
benPearce
There is a problem with this. What happens if the second montor is removed from the computer after the application has been using it ?(MySql Query Brower has this problem)
Charles Faiga
+11  A: 

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.

Barry Kelly
Thanks, I used the Screen.MonitorCount as you and Jim suggested.
stukelly
You should also validate the saved monitor before using the settings on startup. Otherwise your window will not show up on the screen at all if the user removes a monitor that used to be there.
psoul
Starting an app on negative screen coordinates is always fun watching users how to get the app to show...
Jeroen Pluimers
+11  A: 

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.

Jim McKeeth
Thanks for the sample code, it worked great.
stukelly
A: 

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;
Uwe Raabe