Page 1 of 1
Multiple display positions
Posted: Tue Jul 25, 2006 11:41 am
by phuckstepp
I'm trying to create a multi monitor application in PureBasic 4 and I need to know the relative positions of each of the additional monitors.
For Example, I have my right secondary monitor at a position of -192.
I found some PB3.9x code for this but it doesn't work in PB4, can anyone point me in the right direction?
Thanks in advance.
Re: Multiple display positions
Posted: Tue Jul 25, 2006 11:46 am
by Phoenix
Why not show the PB3.9x code and someone can update it to version 4 for you....
Posted: Tue Jul 25, 2006 11:49 am
by phuckstepp
Posted: Tue Jul 25, 2006 12:03 pm
by Flype
Hello,
Why not use ExamineDeskstop() / DesktopWidth() / DesktopHeight() / builtins commands of PB4.0 ?
Posted: Tue Jul 25, 2006 12:21 pm
by phuckstepp
Those commands only give the dimensions of the extra displays and not the actual location of the display, i.e. If I set my secondary monitor directly above my primary I need to know that its location is 0,-1024 in relation to the primary screen at 0,0
Posted: Tue Jul 25, 2006 12:26 pm
by freak
There are just the usual 3.94->4.0 changes needed to make this code work.
Comment out the DISPLAY_DEVICE structure as it is declared in v4, and
put a Global before the linkedlist and global variables (lines 103-105).
They should look like this:
Code: Select all
Global x_monitor_n.l = 0 ; number of monitors is... zero? :-)
Global NewList x_monitor.x_monitorinfo() ; info on monitors
Global x_desktop.x_monitorinfo ; info on desktop
It now compiles and displays the correct results on PB4 on my two monitor system.
Posted: Tue Jul 25, 2006 12:39 pm
by phuckstepp
As simple as that
Thanks.
Posted: Tue Jul 25, 2006 12:44 pm
by phuckstepp
Here's the final v4 updated code:
Code: Select all
; purebasic survival guide
; multi_monitor_2.pb - 30.12.2003 ejn (blueznl)
; http://www.xs4all.nl/~bluez/datatalk/pure1.htm
;
; - how to detect multiple monitors and their relative position to each other
; - EndumDisplayMonitors_()
; - EnumDisplayDevices_()
; - EnumDisplaySettings_()
; - MonitorFromPoint_()
; - GetMonitorInfo_()
;
; constants / structs for multi monitor handling
;
#SM_XVIRTUALSCREEN = 76 ; x-coordinate of left upper corner of total display area
#SM_YVIRTUALSCREEN = 77 ; same for y
#SM_CXVIRTUALSCREEN = 78 ; width
#SM_CYVIRTUALSCREEN = 79 ; height
#SM_CMONITORS = 80 ; number of monitors
#SM_SAMEDISPLAYFORMAT = 81 ; identical sizing of all screens
;
#MONITOR_DEFAULTTONULL = 0
#MONITOR_DEFAULTTOPRIMARY = 1
#MONITOR_DEFAULTTONEAREST = 2
;
#SM_XVIRTUALSCREEN = 76 ; x-coordinate of left upper corner of total display area
#SM_YVIRTUALSCREEN = 77 ; same for y
#SM_CXVIRTUALSCREEN = 78 ; width
#SM_CYVIRTUALSCREEN = 79 ; height
#SM_CMONITORS = 80 ; number of monitors
#SM_SAMEDISPLAYFORMAT = 81 ; identical sizing of all screens
;
#DISPLAY_DEVICE_ATTACHED_TO_DESKTOP = $1
#DISPLAY_DEVICE_MULTI_DRIVER = $2
#DISPLAY_DEVICE_PRIMARY_DEVICE = $4
#DISPLAY_DEVICE_MIRRORING_DRIVER = $8
#DISPLAY_DEVICE_VGA_COMPATIBLE = $10
#DISPLAY_DEVICE_REMOVABLE = $20
#DISPLAY_DEVICE_MODESPRUNED = $8000000
#DISPLAY_DEVICE_REMOTE = $4000000
#DISPLAY_DEVICE_DISCONNECT = $2000000
#DISPLAY_DEVICE_ACTIVE = $1
#DISPLAY_DEVICE_ATTACHED = $2
;
#CCHDEVICENAME = 32
#CCHFORMNAME = 32
;
#ENUM_CURRENT_SETTINGS = -1
#ENUM_REGISTRY_SETTINGS = -2
;
#MONITOR_DEFAULTTONULL = 0
#MONITOR_DEFAULTTOPRIMARY = 1
#MONITOR_DEFAULTTONEAREST = 2
;
Structure MONITORINFO ; used to retrieve monitor info
cb.l ; size of structure (fill before using)
m_x1.l ; rectangle, monitor coords x1/y1/x2/y2
m_y1.l
m_x2.l
m_y2.l
w_x1.l ; rectangle, work area coords (?)
w_y1.l
w_x2.l
w_y2.l
flags.l
EndStructure
;
Structure MONITORINFOEX ; superset of MONITORINFO with added string for devicename
cb.l
m_x1.l
m_y1.l
m_x2.l
m_y2.l
w_x1.l
w_y1.l
w_x2.l
w_y2.l
flags.l
name.b[32] ; #CCHDEVICENAME = 32
EndStructure
;
;
Structure x_monitorinfo ; used to store monitor info
n.l ; sequential number
hnd.l ; handle
x.l ; x-position
y.l ; y-position
w.l ; width
h.l ; height
d.l ; colour depth (bits)
f.l ; frequency
name.s ; devicename (i want my fixed length strings!)
flags.l ; status of the device
EndStructure
;
Global x_monitor_n.l = 0 ; number of monitors is... zero? :-)
Global NewList x_monitor.x_monitorinfo() ; info on monitors
Global x_desktop.x_monitorinfo ; info on desktop
Procedure x_monitor_monitorenumproc(WindowID, Message, WPARAM, LPARAM)
;
; store on each call the monitor handle in the x_monitor() list
; called by windows in callback as set up in x_monitor_detect() by the api EnumDisplayMonitors_()
; also known as MonitorEnumProc
;
AddElement(x_monitor())
x_monitor()\hnd = WindowID
;
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure.l x_monitor_detect()
Protected info.MONITORINFOEX, device.DISPLAY_DEVICE, n.l
Global x_retval.l, x_monitor_n.l, x_desktop.x_monitorinfo
Global x_monitor_samedisplayformat.l
;
; *** detect number of screens and retrieve their properties
;
; in:
; retval:
; out: x_monitor_n.l - number of screens
; x_desktop_w.l - desktop width
; x_desktop_h.l - desktop height
;
; GetSystemMetrics_()
;
; provides quite a bit info on display adapters, screens etc. but does not provide info
; per monitor / device on multi monitor setups
;
; x_monitor_n = GetSystemMetrics_(#SM_CMONITORS)
; x_monitor_samedisplayformat.l = GetSystemMetrics_(#SM_SAMEDISPLAYFORMAT)
;
x_desktop\w = GetSystemMetrics_(#SM_CXVIRTUALSCREEN)
x_desktop\h = GetSystemMetrics_(#SM_CYVIRTUALSCREEN)
;
; Debug "same display format on all screens (0 = no)"
; Debug x_monitor_samedisplayformat
; Debug "counted using getsystemmetrics"
; Debug x_monitor_n
;
; EnumDisplayMonitors()
;
; returns monitors overlapping a given rectangle, including pseudo / mirror monitors!
; after the call, for each monitor a handle will be stored in x_monitor()\hnd
; this can be used to obtain more information using GetMonitorInfo_()
; flags returned are different from EnumDisplayDevices()
;
; ClearList(x_monitor())
; EnumDisplayMonitors_(0,0,@x_monitor_monitorenumproc(),0) ; call the function
; info.MONITORINFOEX ; create a struct for GetMonitorInfo_()
; info\cb = SizeOf(info) ; length of struct (important for MONITORINFO vs. MONITORINFOEX)
; x_monitor_n = 0 ; nr. of monitors
; ResetList(x_monitor()) ; reset and...
; While NextElement(x_monitor()) ; go through the list
; x_monitor_n = x_monitor_n+1
; x_monitor()\n = x_monitor_n ; sequential number
; GetMonitorInfo_(x_monitor()\hnd,@info) ; get info on the monitor
; x_monitor()\x = info\m_x1
; x_monitor()\y = info\m_y1
; x_monitor()\w = info\m_x2 - info\m_x1
; x_monitor()\h = info\m_y2 - info\m_y1
; x_monitor()\name = PeekS(@info\name,32) ; i want my fixed length strings!
; Wend
; ;
; Debug "counted using enumdisplaymonitors"
; Debug x_monitor_n
;
; EnumDisplayDevices()
;
; walks through all available devices, retrieve names and flags
; by using the returned flags all 'non-real' monitors can be filtered out
;
device.DISPLAY_DEVICE ; to store results from EnumDisplayDevices_()
device\cb = SizeOf(DISPLAY_DEVICE)
settings.DEVMODE ; to store results from EnumDisplaySettings_()
settings\dmSize = SizeOf(settings) ; DEVMODE is declared in purebasic itself
settings\dmDriverExtra = 0
;
ClearList(x_monitor())
n.l = 0
x_monitor_n = 0
While EnumDisplayDevices_(0,n,@device,0) > 0 ; check all devices
n = n+1
;
; the StateFlags field in the filled struct contains information on the device / monitor
; some values to check with (not all cards / drivers support all functions):
;
; #DISPLAY_DEVICE_ATTACHED_TO_DESKTOP - in use and part of the desktop
; #DISPLAY_DEVICE_PRIMARY_DEVICE - primary device
; #DISPLAY_DEVICE_VGA_COMPATIBLE - none reported
; #DISPLAY_DEVICE_MULTI_DRIVER
; #DISPLAY_DEVICE_ACTIVE
; #DISPLAY_DEVICE_ATTACHED
;
If device\StateFlags & #DISPLAY_DEVICE_ATTACHED_TO_DESKTOP ; check if it's part of the desktop
;
; if a device is part of the desktop, additional information can be retrieved using
; EnumDisplaySettings_() with the device name
;
If EnumDisplaySettings_(@device\DeviceName,#ENUM_CURRENT_SETTINGS,@settings) > 0
;
; first store some info found via EnumDisplayDevices_()
;
AddElement(x_monitor())
x_monitor_n = x_monitor_n+1
x_monitor()\n = x_monitor_n
x_monitor()\name = PeekS(@device\DeviceName,32) ; i want my fixed length strings!
x_monitor()\flags = device\StateFlags
; and more stuff found via EnumDisplaySettings_()
;
x_monitor()\f = settings\dmDisplayFrequency
x_monitor()\d = settings\dmBitsPerPel
x_monitor()\w = settings\dmPelsWidth
x_monitor()\h = settings\dmPelsHeight
x_monitor()\x = PeekL(@settings\dmOrientation) ; the default definition in purebasic didn't include the onion, well, this works as well
x_monitor()\y = PeekL(@settings\dmPaperLength)
;
; still, the handle is missing, so find that one using a point that is somewhere on the monitor
;
x_monitor()\hnd = MonitorFromPoint_(x_monitor()\x,x_monitor()\y,#MONITOR_DEFAULTTONULL)
;
EndIf
EndIf
Wend
;
; Debug "counted using enumdisplaydevices"
; Debug x_monitor_n
;
x_retval = x_monitor_n
ProcedureReturn x_retval
EndProcedure
x_monitor_detect()
ResetList(x_monitor())
While NextElement(x_monitor())
Debug ""
Debug "monitor "+Str(x_monitor()\n)
If x_monitor()\flags & #DISPLAY_DEVICE_PRIMARY_DEVICE
Debug "primary display"
EndIf
Debug "name "+x_monitor()\name
Debug "handle "+Str(x_monitor()\hnd)
Debug "pos x "+Str(x_monitor()\x)
Debug "pos y "+Str(x_monitor()\y)
Debug "width "+Str(x_monitor()\w)
Debug "height "+Str(x_monitor()\h)
Debug "depth "+Str(x_monitor()\d)
Debug "refresh "+Str(x_monitor()\f)
Wend
Posted: Tue Jul 25, 2006 1:52 pm
by blueznl
good, that saves me rewriting

Posted: Tue Jul 25, 2006 4:28 pm
by Jan Vooijs
Posted: Thu Jul 27, 2006 2:34 pm
by Flype
Well, i like this stuff.
I needed it for personal use, so i made my own include/userlib/subsystem.
There are functions for Absolute size of the desktop,
but also functions for the so called 'WorkArea' size,
and also functions for absolute (#PB_Ignore) or relative mouse position (#Desktop),
and some others cool features.
See here (1rst post) for beta testing (and last post for the functions list) :
http://www.purebasic.fr/english/viewtop ... highlight=
