Mehrere Monitore

Konzeptionelles, Technisches, Termine, Fragen zum Hersteller usw.

Moderator: Moderatoren

Antworten
Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 87
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Mehrere Monitore

Beitrag von Statler » Sa, 12. Mai 2018 12:07

Hallo zusammen,

durch das Forum wurde ich auf die Loesung von "Pablo" aufmerksam gemacht, welche via DLL-Call Informationen ueber die Anzahl, Position und Groesse der Monitore einliest. Ich habe mich ein wenig mit dem Windows Koordinatensysthem beschaeftigt. Hier das Ergebniss.

Falls es jemanden Interessiert ...

Der primaere Monitor dient als Bezugssysthem fuer die sekundaeren Monitore, muss also ermittelt werden:

AEVAL (aMonitors, {|oMonitor| oMonitorP:= IIF (lAnd (oMonitor:dwFlags, 1), oMonitor, oMonitorP)})

Danach kann man die Koordinaten des gewuenschen Monitors ermitteln. Der Workspace beruecksichtigt die Taskleiste, egal ob sie unten oben, rechts odel links liegt. Sofern der reine Monitor interessiert, einfach "rcWork" gegen "rcMonitor" tauschen.

* oMonitorP: Primaerer Monitor (Bezugssysthem)
* oMonitorA: Gewünschter Monitor
*
* Untere, Linke Koordinate des Gewünschten Workspaces
*=====================================================
* nPosX:= oMonitorA:rcWork:left
* nPosY:= oMonitorP:rcMonitor:bottom - oMonitorA:rcWork:bottom
*
* Obere, Rechte Koordinate des Gewünschten Workspaces
*=====================================================
* nPosX:= oMonitorA:rcWork:right
* nPosY:= oMonitorP:rcMonitor:bottom - oMonitorA:rcWork:top
*
* Abmessung des gewünschten Workspaces
*======================================
* nSizeX:= oMonitorA:rcWork:right - oMonitorA:rcWork:left
* nSizeY:= oMonitorA:rcWork:bottom - oMonitorA:rcWork:top

Hier der leicht modifizierte und nachkommentierte Code von Pablo. In dem Struct ist meiner Meinung nach Top und Bottom verwechselt, ich habe das aber so gelassen, damit keine Kompatibilitaetsprobleme auftreten. Falls der DLL'Call keine Ergenisse liefert, warum auch immer, wird ein generischer Monitor mit 1280*1024 zurueckgegeben. Damit ist sichergestellt, das die Applikation zumindest noch startet.

Damit das funktioniert:

#include "ot4xb.ch" und "cbk_MonitorEnum.obj" einbinden

Gruss

Code: Alles auswählen

*
*
*******************************************************************
*******************************************************************
*******************************************************************
***                                                             ***
***   Programmname: GetMonitorInfoArray ()                      ***
***   Funktion:     Holt Minitor Info's via DLL-Call.           ***
***                                                             ***
***   powerd by:    Pablo Botella Navarro, (c) 2004 - 2017      ***
***                                                             ***
*******************************************************************
*******************************************************************
*
FUNCTION GetMonitorInfoArray ()
*
*******************************************************************
*                                                Lokale Variablen *
*******************************************************************
*
LOCAL hData:= _Var2Con ({}),;
      aData:= {}
*
*******************************************************************
*                                  Monitor Informationen einlesen *
*******************************************************************
*
@user32:EnumDisplayMonitors (0, 0, _callback_MonitorEnumProc (), hData)
*
aData:= _ConRelease (hData)
*
*******************************************************************
*                                                          Plan-B *
*******************************************************************
*
IF EMPTY (aData)
   AADD (aData, MONITORINFOEX ():New ())
   *
   aData [1]:cbSize:=           72
   aData [1]:rcMonitor:left:=   0
   aData [1]:rcMonitor:top:=    0
   aData [1]:rcMonitor:right:=  1280
   aData [1]:rcMonitor:bottom:= 1024
   aData [1]:rcWork:left:=      0
   aData [1]:rcWork:top:=       0
   aData [1]:rcWork:right:=     1280
   aData [1]:rcWork:bottom:=    984
   aData [1]:dwFlags:=          1
   aData [1]:szDevice:=         "Generic Display"
ENDIF
*
*******************************************************************
*                                                       Das war`s *
*******************************************************************
*
RETURN (aData)
*
*
*******************************************************************
*******************************************************************
*******************************************************************
***                                                             ***
***   Programmname: MonitorEnumProc ()                          ***
***   Funktion:     Callback fuer @user32:EnumDisplayMonitors.  ***
***                 CBK_MonitorEnum.cbk kann mittels XBPcbk.exe ***
***                 compiliert werden. CBK_MonitorEnum.obj kann ***
***                 alternativ vorcompiliert gelinkt werden.    ***
***                                                             ***
***   powerd by:    Pablo Botella Navarro, (c) 2004 - 2017      ***
***                                                             ***
*******************************************************************
*******************************************************************
*
FUNCTION MonitorEnumProc (hMonitor, hDC, pRect, hData)
*
*******************************************************************
*                                                Lokale Variablen *
*******************************************************************
*
LOCAL oMonitor:= MONITORINFOEX ():New (),;
      aData:=    _Con2Var (hData)
*
*******************************************************************
*                                  Monitor Informationen einlesen *
*******************************************************************
*
oMonitor:cbSize:= oMonitor:_SizeOf_ ()
*
IF @user32:GetMonitorInfoA (hMonitor, oMonitor) != 0
   AADD (aData, oMonitor)
*  ELSE
*  AADD (aData, NIL)
ENDIF
*
*******************************************************************
*                                                       Das war`s *
*******************************************************************
*
RETURN (.T.)
*
*******************************************************************
*                             Strukte fuer GetMonitorInfoArray () *
*******************************************************************
*
BEGIN STRUCTURE MONITORINFOEX
   MEMBER DWORD    cbSize 
   MEMBER @ RECT   rcMonitor
   MEMBER @ RECT   rcWork 
   MEMBER DWORD    dwFlags 
   MEMBER SZSTR    szDevice SIZE 32
END STRUCTURE
*
BEGIN STRUCTURE  RECT
  MEMBER LONG left 
  MEMBER LONG top 
  MEMBER LONG right 
  MEMBER LONG bottom 
END STRUCTURE

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 11515
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Mehrere Monitore

Beitrag von AUGE_OHR » Sa, 12. Mai 2018 17:57

Statler hat geschrieben:
Sa, 12. Mai 2018 12:07
In dem Struct ist meiner Meinung nach Top und Bottom verwechselt
bei Windows ist 0,0 oben links, bei Xbase++ default unten links.

man kann es aber für Xbase++ ändern

Code: Alles auswählen

LOCAL aPres := { { XBP_PP_ORIGIN, XBP_ORIGIN_TOPLEFT } }

   oDlg := XbpDialog():new(AppDeskTop() ,, {50,30}, {300,200}, aPres ) 
gruss by OHR
Jimmy

Antworten