Virtual Screen info and multiple monitor info!

Share your advanced PureBasic knowledge/code with the community.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Virtual Screen info and multiple monitor info!

Post by Rescator »

Code updated For 5.20+


I hope some of you find this interesting,
especially the virtual screen stuff is something I myself recently learned!
The multiple monitor stuff however is very similar to PureBasic's DekstopEnumeration functions.

Fallbacks have been added for Win95 and NT (which do not support multiple monitors)
So there should always be at least 1 display.
(If there is ever 0 displays in the list, something failed somewhere)

Code: Select all

    ;System metrics can vary from display to display.

    ;Constants needed. Win98/Me and Windows 5.x (2K,XP,etc) )and later only
    #SM_XVIRTUALSCREEN=76
    #SM_YVIRTUALSCREEN=77
    #SM_CXVIRTUALSCREEN=78
    #SM_CYVIRTUALSCREEN=79
    #SM_CMONITORS=80

    ;GetSystemMetrics(SM_CMONITORS) counts only display monitors.
    ;This is different from EnumDisplayMonitors,
    ;which enumerates display monitors and non-display pseudo-monitors.
    Procedure.i MonitorCount()
     Protected result.i=1
     If OSVersion()>#PB_OS_Windows_NT_4
      result=GetSystemMetrics_(#SM_CMONITORS)
     EndIf
     ProcedureReturn result
    EndProcedure

    Procedure.i VirtualScreenWidth()
     Protected result.i
     If OSVersion()>#PB_OS_Windows_NT_4
      result=GetSystemMetrics_(#SM_CXVIRTUALSCREEN)
     Else
      result=GetSystemMetrics_(#SM_CXSCREEN)
     EndIf
     ProcedureReturn result
    EndProcedure

    Procedure.i VirtualScreenHeight()
     Protected result.i
     If OSVersion()>#PB_OS_Windows_NT_4
      result=GetSystemMetrics_(#SM_CYVIRTUALSCREEN)
     Else
      result=GetSystemMetrics_(#SM_CYSCREEN)
     EndIf
     ProcedureReturn result
    EndProcedure

    Procedure.i VirtualScreenX()
     Protected result.i=0
     If OSVersion()>#PB_OS_Windows_NT_4
      result=GetSystemMetrics_(#SM_XVIRTUALSCREEN)
     EndIf
     ProcedureReturn result
    EndProcedure

    Procedure.i VirtualScreenY()
     Protected result.i=0
     If OSVersion()>#PB_OS_Windows_NT_4
      result=GetSystemMetrics_(#SM_YVIRTUALSCREEN)
     EndIf
     ProcedureReturn result
    EndProcedure


    Debug "Display Monitors: "+Str(MonitorCount())
    Debug "Virtual Screen Size: "+Str(VirtualScreenWidth())+"x"+Str(VirtualScreenHeight())
    Debug "Virtual Screen X,Y: "+Str(VirtualScreenX())+", "+Str(VirtualScreenY())
    Debug ""

    ;Monitor enumeration
    Structure displaymonitors_struct
     primary.i
     x.i
     y.i
     width.i
     height.i
     depth.i
     refresh.i
     display.s
    EndStructure

    NewList DisplayMonitors.displaymonitors_struct()

;     Structure MONITORINFOEX
;      cbSize.i
;      rcMonitor.RECT
;      rcWork.RECT
;      dwFlags.i
;      szDevice.s{#CCHDEVICENAME}
;     EndStructure

    #MONITORINFOF_PRIMARY=$1
    #VREFRESH=116
    Procedure.i EnumDisplayMonitorsProc(monitor.i,dc.i,*rect.RECT,userdata.i)
     Protected mi.MONITORINFOEX
     Shared DisplayMonitors()
     mi\cbSize=SizeOf(MONITORINFOEX)
     GetMonitorInfo_(monitor,mi)
     AddElement(DisplayMonitors())
     DisplayMonitors()\display=mi\szDevice
     DisplayMonitors()\x=mi\rcMonitor\left
     DisplayMonitors()\y=mi\rcMonitor\top
     DisplayMonitors()\width=mi\rcMonitor\right-mi\rcMonitor\left
     DisplayMonitors()\height=mi\rcMonitor\bottom-mi\rcMonitor\top
     If (mi\dwFlags & #MONITORINFOF_PRIMARY)=#MONITORINFOF_PRIMARY
      DisplayMonitors()\primary=#True
     Else
      DisplayMonitors()\primary=#False
     EndIf
     DisplayMonitors()\depth=GetDeviceCaps_(dc,#BITSPIXEL)
     DisplayMonitors()\refresh=GetDeviceCaps_(dc,#VREFRESH)
     ProcedureReturn #True
    EndProcedure

    #ENUM_CURRENT_SETTINGS=-1
    Procedure.i DisplayEnumerate()
     Shared DisplayMonitors()
     Protected dc.i,dev.DEVMODE
     ClearList(DisplayMonitors())
     If OSVersion()>#PB_OS_Windows_NT_4
      dc=GetDC_(#Null)
      EnumDisplayMonitors_(dc,#Null,@EnumDisplayMonitorsProc(),0)
      If dc : ReleaseDC_(#Null,dc) : EndIf
     Else
      AddElement(DisplayMonitors())
      DisplayMonitors()\display="DISPLAY"
      DisplayMonitors()\x=0
      DisplayMonitors()\y=0
      DisplayMonitors()\width=GetSystemMetrics_(#SM_CXSCREEN)
      DisplayMonitors()\height=GetSystemMetrics_(#SM_CYSCREEN)
      DisplayMonitors()\primary=#True
      If EnumDisplaySettings_(#Null,#ENUM_CURRENT_SETTINGS,dev)
       DisplayMonitors()\depth=dev\dmBitsPerPel
       DisplayMonitors()\refresh=dev\dmDisplayFrequency
      Else
       DisplayMonitors()\depth=16
       DisplayMonitors()\refresh=60
      EndIf
     EndIf
     ProcedureReturn ListSize(DisplayMonitors())
    EndProcedure

    Debug "Display Count: "+Str(DisplayEnumerate()) ;May differ (more) from MonitorCount()

    ForEach DisplayMonitors()
     Debug "Display Name: "+DisplayMonitors()\display
     If DisplayMonitors()\primary
      Debug "Display Primary: "+"True"
     Else
      Debug "Display Primary: "+"False"
     EndIf
     Debug "Display Depth: "+Str(DisplayMonitors()\depth)+"bit"
     Debug "Display Refresh: "+Str(DisplayMonitors()\refresh)+"Hz"
     Debug "Display X,Y: "+Str(DisplayMonitors()\x)+", "+Str(DisplayMonitors()\y)
     Debug "Display Size: "+Str(DisplayMonitors()\width)+"x"+Str(DisplayMonitors()\height)
     Debug ""
    Next
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

some more info may be found here (for 3.94 though)

http://www.purebasic.fr/english/viewtop ... ti+monitor
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Haha! talk about re-inventing the wheel!
I even remember reading/testing the code from that thread. (some time ago)
Oh well! Better to have too much examples than too few :lol:
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

After comparing mine and blueznl's code, it seems his code has to exclude non displays (virtual displays etc),
while my code above seem to not include them at all.
In which case MonitorCount() and my use of EnumDisplayMonitors should always match in count of actual (monitor) displays hopefully.
(M$ docs aren't really helpfull in that respect, could be incorrect?)
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

i wanted to list all active monitors (which were part of the desktop)

with enumdisplaymonitors i would also get non-active devices, and i did not figure out how to distinguish between active and non-active monitors, also certain devices would not show up

then again, it's so long ago, i don't remember the details anymore, so i coudl be totally wrong :-)

at least i agree with you on m$'s documentation :-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Post Reply