Jump to content

Multi Monitor library

Recommended Posts

Dear All

I have two monitors as most of you today and i am struggled to find a library as complete as possible that allows to manage them independently.

So at the end I decided to write one myself, collecting as much info as possible from this forum and around the web.


Must say Msn and our Microsoft friends also provide a lot of support but it is so fragmented that it is almost impossible to make sense of it sometimes.

So here are all the functions you will find



_NumberAndNameMonitors = provides basic information about all monitors, included the regkey

_DisplayKeySettings = generates a basic array with all the key info about each monitor

_DisplayChangeSettings = allows you to modify monitor res, position, rotation ... and many other options

_MonitorAndDesktopInfo = Key to understand the size of both the desktop as well as the working area

_DisplayChangeAcceleration = To change hardware acceleration of each monitor independently

_ReadGamma = read the gamma setup of your desktop

_WriteGamma = modify the gamma setup of your desktop color by color

_ToggleMonitor = switch on off standby all your monitors at the same time

_MultiMonitorScreenSaver= Any screensaver working on only one monitor at the time at your choice

_SaveDesktopIcons = Save the icons existing all around your desktops

_RestoreDesktopIcons = Restore only those icons on the monitor of your choice

Now please help and contribute

I am still dreaming to add more functions to the library such as

- Multi desktop -- activate several desktops on a multi monitor at the same time

- Toggle single monitor on/off

- Change fonts 1 monitor at the time

.... you name it

I am sure lots of you know how to do great things and this can be seen just as a starting point :)


Link to post
Share on other sites
  • 3 weeks later...

I like the library. However, I'm having problems switching the primary display. You mention that it needs to be used in conjunction with option 7. How do you do this? Thanks again for the library.

You are welcome. I would have loved also some other input and code from any of the 43 people that have downloaded. I am so keen in implementing the multi-desktop but still no luck.

this said:

Primary display is A big problem. things are very different if you play with double video card or with one with extension

In the latter case no chance i did not manage to make it work

in the former instead:

then use option 7 to switch off any of the two monitors, make the other primary. (primary is always positioned as 0,0) Reset the position of the switched off monitor

$KeySettings[$Index][2] = xxxxx; you decide
$KeySettings[$Index][3]= yyyyy

and reactivate it

_DisplayChangeSettings(7, $KeySettings, $Index = [MONITOR OF YOUR CHOICE])

It works on my system but..... let me know how it goes on yours

Link to post
Share on other sites
  • 3 years later...

Old and forgotten, STILL very useful!



Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...
Link to post
Share on other sites
  • 11 months later...

Hermano, if you ever get a chance to read this, I have an idea to make it so that you can figure the locations of each monitor relative to the default monitor's location, by adding a small section to the library, and it will work with many monitors at different layers of heights and spans.

Edited by mechaflash213

“Hello, ladies, look at your man, now back to me, now back at your man, now back to me. Sadly, he isn’t me, but if he stopped using ladies scented body wash and switched to Old Spice, he could smell like he’s me. Look down, back up, where are you? You’re on a boat with the man your man could smell like. What’s in your hand, back at me. I have it, it’s an oyster with two tickets to that thing you love. Look again, the tickets are now diamonds. Anything is possible when your man smells like Old Spice and not a lady. I’m on a horse.”


Link to post
Share on other sites
  • 2 months later...

Due to the recent changes in Win7 API I had to update part of the library. A good opportunity to make it even more flexible and to provide relative and absolute coords for the monitors relative to the mailn one

here the updated functions:

You call Monitors() only as a function and you have the array will all the Monitors info you need for your coding

;============================================================================================== _NumberAndNameMonitors
; Function Name:    _NumberAndNameMonitors ()
; Description:   Provides the first key elements of a multimonitor system, included the Regedit Keys
; Parameter(s):   None
; Return Value(s):   $NumberAndName [][]
;~        [0][0] total number of video devices
;;       [x][1] name of the device
;;       [x][2] name of the adapter
;;       [x][3] monitor flags (value is returned in Hex str -convert in DEC before use with Bitand)
;;       [x][4] registry key of the device
; Remarks:   the flag value [x][3] can be one of the following
;;             DISPLAY_DEVICE_MULTI_DRIVER       0x00000002
;;            DISPLAY_DEVICE_PRIMARY_DEVICE    0x00000004
;;            DISPLAY_DEVICE_VGA               0x00000010
;;        DISPLAY_MIRROR_DEVICE  0X00000008
;;        DISPLAY_REMOVABLE  0X00000020
; Author(s):        Hermano
Func _NumberAndNameMonitors()
Local $dev = -1, $id = 0, $msg_ = "", $EnumDisplays, $StateFlag
Dim $NumberAndName[2][6]
Local $DISPLAY_DEVICE = DllStructCreate("int;char[32];char[128];int;char[128];char[128]")
DllStructSetData($DISPLAY_DEVICE, 1, DllStructGetSize($DISPLAY_DEVICE))
Dim $dll = "user32.dll"
  $dev += 1
  $EnumDisplays = DllCall($dll, "int", "EnumDisplayDevices", "ptr", 0, "int", $dev, "ptr", DllStructGetPtr($DISPLAY_DEVICE), "int", 1)
  If $EnumDisplays[0] <> 0 Then
   ReDim $NumberAndName[$dev + 2][6]
   $NumberAndName[$dev + 1][1] = DllStructGetData($DISPLAY_DEVICE, 2) ;device Name
   $NumberAndName[$dev + 1][2] = DllStructGetData($DISPLAY_DEVICE, 3) ;device or display description
   $NumberAndName[$dev + 1][3] = Hex(DllStructGetData($DISPLAY_DEVICE, 4)) ;all flags (value in HEX)
   $NumberAndName[$dev + 1][4] = DllStructGetData($DISPLAY_DEVICE, 6) ;registry key of the device
   $NumberAndName[$dev + 1][5] = DllStructGetData($DISPLAY_DEVICE, 5) ;hardware interface name
Until $EnumDisplays[0] = 0
$NumberAndName[0][0] += $dev
Return $NumberAndName
EndFunc   ;==>_NumberAndNameMonitors
;============================================================================================== _DisplayKeySettings
; Function Name:    _DisplayKeySettings($MonName,$Opt = -1)
; Description:   all key information about each adapter needed to properly change the display setting
; Parameter(s):   $MonName  =   return array from _NumberAndNameMonitors
;;    $Opt  = -1  $ENUM_CURRENT_SETTINGS [default]
; Return Value(s):   $KeySettings[][]
;;        $KeySettings[0][0] =  Number of non virtual devices
;;        $KeySettings[x][0] =  Flags
;;        $KeySettings[x][1] =  Monitor Name
;;        $KeySettings[x][2] = up left desktop position X
;;        $KeySettings[x][3] = up left desktop position Y
;;        $KeySettings[x][4] = Width (resolution)
;;        $KeySettings[x][5] = Heigth (resolution)
;;        $KeySettings[x][6] = Bpp color (resolution)
;;        $KeySettings[x][7] = Screen Refresh(resolution)
;;        $KeySettings[x][8] = Display Orientation
;;        $KeySettings[x][9] = Display Fixed Output
; Remarks:
; Author(s):        Hermano
Func _DisplayKeySettings($MonName, $Opt = -1)
Dim $KeySettings[1][10], $i, $Dn = 0, $res
If Not IsArray($MonName) Then $MonName = _NumberAndNameMonitors()
Local $DEVMODE = DllStructCreate("char[32];short[4];int[5];short[5];byte[32];short;int[6]")
DllStructSetData($DEVMODE, 2, DllStructGetSize($DEVMODE), 3)
For $i = 1 To $MonName[0][0]
   $Dn += 1
   $res = DllCall("user32.dll", "int", "EnumDisplaySettings", "str", $MonName[$i][1], "int", $Opt, "ptr", DllStructGetPtr($DEVMODE))
   If $res[0] = 0 Then _
     $res = DllCall("user32.dll", "int", "EnumDisplaySettings", "str", $MonName[$i][1], "int", Mod($Opt, 2) - 1, "ptr", DllStructGetPtr($DEVMODE))
   ReDim $KeySettings[1 + $Dn][10]
   $KeySettings[$Dn][0] = $MonName[$i][3] ;flags
   $KeySettings[$Dn][1] = $MonName[$i][1] ;name
   $KeySettings[$Dn][2] = DllStructGetData($DEVMODE, 3, 2) ;up left desktop position coord X
   $KeySettings[$Dn][3] = DllStructGetData($DEVMODE, 3, 3) ;up left desktop position coord Y
   $KeySettings[$Dn][4] = DllStructGetData($DEVMODE, 7, 2) ;Width (resolution)
   $KeySettings[$Dn][5] = DllStructGetData($DEVMODE, 7, 3) ;Heigth (resolution)
   $KeySettings[$Dn][6] = DllStructGetData($DEVMODE, 7, 1) ;Bpp color (resolution)
   $KeySettings[$Dn][7] = DllStructGetData($DEVMODE, 7, 5) ;Screen Refresh(resolution)
   $KeySettings[$Dn][8] = DllStructGetData($DEVMODE, 3, 4) ;Display Orientation
   $KeySettings[$Dn][9] = DllStructGetData($DEVMODE, 3, 5) ;fixed output
$KeySettings[0][0] = $Dn
Return $KeySettings
EndFunc   ;==>_DisplayKeySettings
;============================================================================================== Monitors Selection
Func Monitors()
$a = _DisplayKeySettings(_NumberAndNameMonitors(), -1)
For $dum = 1 To $a[0][0]
  If BitAND($a[$dum][0], 1) Then ;I make sure is not a virtual monitor
   $Monitors += 1
   ReDim $MonitorCoords[$Monitors + 1][5]
   $MonitorCoords[$Monitors][1] = $a[$dum][2];X
   $MonitorCoords[$Monitors][2] = $a[$dum][3];Y
   $MonitorCoords[$Monitors][3] = Abs($a[$dum][2] + $a[$dum][4]);XX
   $MonitorCoords[$Monitors][4] = Abs($a[$dum][5] + $a[$dum][3]);YY
$MonitorCoords[0][0] = $Monitors
EndFunc   ;==>Monitors
Edited by Hermano
Link to post
Share on other sites
  • 2 years later...

I found a bug (_MonitorAndDesktopInfo was returning lots of junk data) and the fix for it is:

in line 319,


If Mod($KeySettings[$i][0], 2) <> 0 Then _                        ; just to be sure it is a real monitor


If Mod($KeySettings[$i][0], 2) <> 0 Then                       ; just to be sure it is a real monitor

And after line 333's EndIf add another



Edited by anandchakru
[font="Book Antiqua"]Thanks`A[/font]
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...