Share this page 

Display on the second monitorTag(s): WinAPI/Registry


When you have more than one screen attached to a PC, one possible configuration is to see the dual monitors setup as a virtual desktop.

The trick is to get the resolution of the first monitor (the main one) and then position a window on the second screen (right monitor).

First you need to this API to detect if more than one monitor is present.

[local external function definition]
FUNCTION Integer GetSystemMetrics (Integer nIndex) LIBRARY "user32.dll"
In the open event of a window, we position the window at the max value of screen resolution returned by the Powerbuiler environment object.
integer SM_CMONITORS  = 80
environment myEnv

IF GetSystemMetrics(SM_CMONITORS)> 1 THEN
   GetEnvironment(myEnv)
   // display on the secondary monitor (right to primary monitor!)
   this.x = PixelsToUnits(myEnv.ScreenWidth, XPixelsToUnits!)
   this.y = 0
END IF
Now if you want to center the window displayed on the second monitor, you need to get the resolution on that monitor. The Powerbuilder environment object returns only the resolution of the main monitor. To get the resolution of the second monitor, you need to call two Windows APIs.
[local external function definition]
FUNCTION Long MonitorFromWindow (Long hwnd, Long dwFlags) LIBRARY "user32"
FUNCTION Long GetMonitorInfo (long hMonitor, ref tagmonitorinfo moninfo) &
     LIBRARY "user32"  ALIAS FOR "GetMonitorInfoA"
A structure, tagmonitorinfo, is defined to contain the informations returned by the API.

We position the window on the second monitor. We call the MonitorFromWindow API to get an identifer for the monitor as seen by Windows. Then with the identifier, we call another API to the associated screen resolution.

integer SM_CMONITORS  = 80
integer MONITOR_DEFAULTTONULL = 0

IF GetSystemMetrics(SM_CMONITORS)> 1 THEN
   environment myEnv
   long monitor
   tagmonitorinfo tmi
   int x1
   int y1

   GetEnvironment(myEnv)
   // move to the second monitor (right to primary monitor!)
   this.x = PixelsToUnits(myEnv.ScreenWidth, XPixelsToUnits!)
   this.y = 0

   // get the resolution of the second monitor
   monitor = MonitorFromWindow(Handle(w_yop), MONITOR_DEFAULTTONULL)

   IF NOT isNull(monitor) THEN
      tmi.cbSize = 72  // size in bytes of TAGMONITORINFO
      GetMonitorInfo(monitor, tmi);
      // the resolution
      x1 = tmi.rcMonitor.right - tmi.rcMonitor.left;
      y1 = tmi.rcMonitor.bottom - tmi.rcMonitor.top;

      // display center on the secondary monitor (right to primary monitor!)
      this.X = PixelsToUnits(myEnv.ScreenWidth, XPixelsToUnits!) + &
          (( PixelsToUnits(x1, XPixelsToUnits!) - this.Width ) / 2)
      this.Y = ( PixelsToUnits( y1,  YPixelsToUnits! ) - this.Height ) /2
   END IF
END IF
If the second monitor is to the left of the primary monitor then to position a window we need to use a negative value.

integer SM_CMONITORS  = 80
integer MONITOR_DEFAULTTONULL = 0

IF GetSystemMetrics(SM_CMONITORS)> 1 THEN
   environment myEnv
   long monitor
   tagmonitorinfo tmi
   int x1
   int y1

   GetEnvironment(myEnv)
   // move to the second monitor (left to primary monitor)
   this.x = -1 * (this.Width)
   this.y = 0

   // get the resolution of the second monitor
   monitor = MonitorFromWindow(Handle(w_yop), MONITOR_DEFAULTTONULL)

   IF NOT isNull(monitor) THEN
      tmi.cbSize = 72  // size in bytes of TAGMONITORINFO
      GetMonitorInfo(monitor, tmi);
      // the resolution
      x1 = tmi.rcMonitor.right - tmi.rcMonitor.left;
      y1 = tmi.rcMonitor.bottom - tmi.rcMonitor.top;

      // display center on the secondary monitor (left to primary monitor!)
      this.X = -1 * (  PixelsToUnits(x1, XPixelsToUnits!) -  &
           (PixelsToUnits(x1, XPixelsToUnits!) - this.Width ) / 2)
      this.Y = ( PixelsToUnits( y1,  YPixelsToUnits! ) - this.Height ) /2
   END IF
END IF