Jump to content

Get All Monitor Info!


fisofo
 Share

Recommended Posts

Well, I've wanted this for a long time, and I finally found out how to do it. The script on this page shows how to get this info in C++/VB, and I converted the stuff I wanted into autoit:

; modified by fisofo
; Last Modified: Jan 20, 2007

Global Const $DISPLAY_DEVICE_ATTACHED_TO_DESKTOP = 0x00000001
Global Const $DISPLAY_DEVICE_MULTI_DRIVER        = 0x00000002
Global Const $DISPLAY_DEVICE_PRIMARY_DEVICE      = 0x00000004
Global Const $DISPLAY_DEVICE_MIRRORING_DRIVER      = 0x00000008

Global Const $DISPLAY_DEVICE_ACTIVE              = 0x00000001
Global Const $DISPLAY_DEVICE_ATTACHED              = 0x00000002

Global Const $ENUM_CURRENT_SETTINGS = -1
Global Const $ENUM_REGISTRY_SETTINGS = -2

Global Const $MONITORINFO = "int;int[4];int[4];int"
Global Const $RECT = "long;long;long;long"
Global Const $DEVMODE = "byte[32];short;short;short;short;int;int[2];int;int" & _
        ";short;short;short;short;short;byte[32]" & _
        ";short;ushort;int;int;int;int"
Global Const $POINTL = "long;long"
Global Const $DISPLAY_DEVICE = "int;char[32];char[128];int;char[128];char[128]"

MonitoInfo()

Func MonitoInfo()
    Dim $MonitorPos[1][5]
    $dev = 0
    $id = 0
    $dll = DllOpen("user32.dll")
    $msg = ""
    
    Dim $dd = DllStructCreate($DISPLAY_DEVICE)
    DllStructSetData($dd, 1, DllStructGetSize($dd))
    
    $EnumDisplays = DllCall($dll, "int", "EnumDisplayDevices", _
            "ptr", 0, _
            "int", $dev, _
            "ptr", DllStructGetPtr($dd), _
            "int", 0)
    $StateFlag = Number(StringMid(Hex(DllStructGetData($dd, 4)), 3))
    While $EnumDisplays[0] <> 0
        If ($StateFlag <> $DISPLAY_DEVICE_MIRRORING_DRIVER) And ($StateFlag <> 0) Then ;ignore virtual mirror displays
            
            ;get information about the display's position and the current display mode
            Dim $dm = DllStructCreate($DEVMODE)
            DllStructSetData($dm, 4, DllStructGetSize($dm))
            $EnumDisplaysEx = DllCall($dll, "int", "EnumDisplaySettingsEx", _
                    "str", DllStructGetData($dd, 2), _
                    "int", $ENUM_CURRENT_SETTINGS, _
                    "ptr", DllStructGetPtr($dm), _
                    "int", 0)
            If $EnumDisplaysEx[0] = 0 Then
                DllCall($dll, "int", "EnumDisplaySettingsEx", _
                        "str", DllStructGetData($dd, 2), _
                        "int", $ENUM_REGISTRY_SETTINGS, _
                        "ptr", DllStructGetPtr($dm), _
                        "int", 0)
            EndIf
            
            ;get the monitor handle and workspace
            Dim $hm
            Dim $mi = DllStructCreate($MONITORINFO)
            DllStructSetData($mi, 1, DllStructGetSize($mi))
            If Mod($StateFlag, 2) <> 0 Then ; $DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
                ;display is enabled. only enabled displays have a monitor handle
                $hm = DllCall($dll, "hwnd", "MonitorFromPoint", _
                        "int", DllStructGetData($dm, 7, 1), _
                        "int", DllStructGetData($dm, 7, 2), _
                        "int", 0)
                If $hm[0] <> 0 Then
                    DllCall($dll, "int", "GetMonitorInfo", _
                            "hwnd", $hm[0], _
                            "ptr", DllStructGetPtr($mi))
                EndIf
            EndIf

            ;format information about this monitor
            If $hm[0] <> 0 Then
                $id += 1
                ReDim $MonitorPos[$id+1][5]
                $MonitorPos[$id][0] = $hm[0]
                $MonitorPos[$id][1] = DllStructGetData($mi, 3, 1)
                $MonitorPos[$id][2] = DllStructGetData($mi, 3, 2)
                $MonitorPos[$id][3] = DllStructGetData($mi, 3, 3)
                $MonitorPos[$id][4] = DllStructGetData($mi, 3, 4)
                ;workspace and monitor handle
                
                ;workspace: x,y - x,y HMONITOR: handle
                $msg &= "workspace:" & $hm[0] & ": " & _
                        DllStructGetData($mi, 3, 1) & "," & _
                        DllStructGetData($mi, 3, 2) & " to " & _
                        DllStructGetData($mi, 3, 3) & "," & _
                        DllStructGetData($mi, 3, 4) & Chr(13)
            EndIf
        EndIf

        $dev += 1
        
        $EnumDisplays = DllCall($dll, "int", "EnumDisplayDevices", _
                "ptr", 0, _
                "int", $dev, _
                "ptr", DllStructGetPtr($dd), _
                "int", 0)
        $StateFlag = Number(StringMid(Hex(DllStructGetData($dd, 4)), 3))
    WEnd
    
    $MonitorPos[0][0] = $id
    DllClose($dll)
    
    MsgBox(0,"",$msg)
    Return $MonitorPos
EndFunc

In this example I'm just pulling the workspace position info. See the msdn pages on the DEVMODE structure and the MONITORINFO structure on other things you can extract, then just modify the code!

I swear I do this with all my scripts, but many thanks to Larry for his help figuring out the structs!

Link to comment
Share on other sites

This is pretty cool, but what do the numbers mean, for each desktop?

(0x0001000, 0x0001003)

[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Link to comment
Share on other sites

This is pretty cool, but what do the numbers mean, for each desktop?

(0x0001000, 0x0001003)

They are the Monitor Handles, very similar to a window handle I guess... except that it's for a monitor :)

Anyway, just a unique handle to each monitor attached to the desktop.

Hey, this is pretty cool. I wish I knew VB or C++ :D

Kurt

Who says I do!?! Seriously, I don't know how much credit I can take here, it took me like a week and a half to figure out that other code, In the end it was really just putting together stuff larry wrote and then getting his help with the rest :D

Edited by fisofo
Link to comment
Share on other sites

  • 1 year later...

Finally I found I want! I did some modifications. If you find any problem, let me know.

;modified by Yibing
;Last modified Feb 13, 2008
MonitoInfo()

Func MonitoInfo()
    Const $DISPLAY_DEVICE_MIRRORING_DRIVER    = 0x00000008
    Const $ENUM_CURRENT_SETTINGS = -1
    Const $DISPLAY_DEVICE = "int;char[32];char[128];int;char[128];char[128]" 
    Const $DEVMODE = "byte[32];short;short;short;short;int;int[2];int;int" & _
                    ";short;short;short;short;short;byte[32]" & _
                    ";short;ushort;int;int;int;int"
                    
    Dim $MonitorPos[1][4]
    $id=0
    $dll = DllOpen("user32.dll")
    $msg = ""

    Dim $dd = DllStructCreate($DISPLAY_DEVICE)
    DllStructSetData($dd, 1, DllStructGetSize($dd))

    Dim $dm = DllStructCreate($DEVMODE)
    DllStructSetData($dm, 4, DllStructGetSize($dm))

    Do
        $EnumDisplays = DllCall($dll, "int", "EnumDisplayDevices", _
                "ptr", "NULL", _
                "int", $id, _
                "ptr", DllStructGetPtr($dd), _
                "int", 0)
        $StateFlag = Number(StringMid(Hex(DllStructGetData($dd, 4)), 3))
        If ($StateFlag <> $DISPLAY_DEVICE_MIRRORING_DRIVER) And ($StateFlag <> 0) Then;ignore virtual mirror displays
            $EnumDisplaysEx = DllCall($dll, "int", "EnumDisplaySettings", _
                    "str", DllStructGetData($dd, 2), _
                    "int", $ENUM_CURRENT_SETTINGS, _
                    "ptr", DllStructGetPtr($dm))
            $MonitorPos[$id][0] = DllStructGetData($dm, 7, 1)
            $MonitorPos[$id][1] = DllStructGetData($dm, 7, 2)
            $MonitorPos[$id][2] = DllStructGetData($dm, 18)
            $MonitorPos[$id][3] = DllStructGetData($dm, 19)
            $msg &= "Monitor " & ($id + 1) & " start point:(" &  _ 
                DllStructGetData($dm, 7, 1) & "," & _
                DllStructGetData($dm, 7, 2) & ") " & @TAB & "Screen resolution: " & _
                DllStructGetData($dm, 18) & "x" & _
                DllStructGetData($dm, 19) & @LF
                ReDim $MonitorPos[$id][5]
            ReDim $MonitorPos[$id+2][5]
        EndIf
        $id += 1
    Until $EnumDisplays[0] = 0

    $MonitorPos[$id-1][0] = $id
    DllClose($dll)

    MsgBox(0,"Screen Info",$msg)

EndFunc
Edited by Yibing
Link to comment
Share on other sites

Yours doesn't work for me.

This is right out of the beta help:

#AutoIt3Wrapper_Au3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <WinAPI.au3>
Opt('MustDeclareVars', 1)

_Main()

Func _Main()
    Local $aDevice, $i = 0, $text
    While 1
        $aDevice = _WinAPI_EnumDisplayDevices("", $i)
        If Not $aDevice[0] Then ExitLoop
        $text = "Successful? " & $aDevice[0] & @LF
        $text &= "Device (Adapter or Monitor): " & $aDevice[1] & @LF
        $text &= "Description (Adapter or Monitor): " & $aDevice[2] & @LF
        $text &= "Device State Flag: " & $aDevice[3] & @LF
        Select
            Case BitAND($aDevice[3], 32) = 32
                $text &= @TAB & "- The device has more display modes than its output devices support" & @LF
                ContinueCase
            Case BitAND($aDevice[3], 16) = 16
                $text &= @TAB & "- The device is removable; it cannot be the primary display" & @LF
                ContinueCase
            Case BitAND($aDevice[3], 8) = 8
                $text &= @TAB & "- The device is VGA compatible" & @LF
                ContinueCase
            Case BitAND($aDevice[3], 4) = 4
                $text &= @TAB & "- Represents a pseudo device used to mirror application drawing for remoting" & @LF
                ContinueCase
            Case BitAND($aDevice[3], 2) = 2
                $text &= @TAB & "- The primary desktop is on the device" & @LF
                ContinueCase
            Case BitAND($aDevice[3], 1) = 1
                $text &= @TAB & "- The device is part of the desktop" & @LF
        EndSelect
        $text &= "Plug and Play identifier string: " & $aDevice[4] & @LF
        MsgBox(0, "", $text)
        $i += 1
    WEnd
EndFunc   ;==>_Main

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Yours doesn't work for me.

Sorry, I made some changes but didn't do further testing. Now the working code:

;modified by Yibing
;Last modified Feb 15, 2008
MonitoInfo()

Func MonitoInfo()
    Const $DISPLAY_DEVICE_MIRRORING_DRIVER    = 0x00000008
    Const $ENUM_CURRENT_SETTINGS = -1
    Const $DISPLAY_DEVICE = "int;char[32];char[128];int;char[128];char[128]"
    Const $DEVMODE = "byte[32];short;short;short;short;int;int[2];int;int" & _
                    ";short;short;short;short;short;byte[32]" & _
                    ";short;ushort;int;int;int;int"
                    
    Dim $MonitorPos[1][4]
    $dev = 0
    $id = 0
    $dll = DllOpen("user32.dll")
    $msg = ""

    Dim $dd = DllStructCreate($DISPLAY_DEVICE)
    DllStructSetData($dd, 1, DllStructGetSize($dd))

    Dim $dm = DllStructCreate($DEVMODE)
    DllStructSetData($dm, 4, DllStructGetSize($dm))

    Do
        $EnumDisplays = DllCall($dll, "int", "EnumDisplayDevices", _
                "ptr", "NULL", _
                "int", $dev, _
                "ptr", DllStructGetPtr($dd), _
                "int", 0)
        $StateFlag = Number(StringMid(Hex(DllStructGetData($dd, 4)), 3))
        If ($StateFlag <> $DISPLAY_DEVICE_MIRRORING_DRIVER) And ($StateFlag <> 0) Then;ignore virtual mirror displays
            $id += 1
            ReDim $MonitorPos[$id+1][5]
            $EnumDisplaysEx = DllCall($dll, "int", "EnumDisplaySettings", _
                    "str", DllStructGetData($dd, 2), _
                    "int", $ENUM_CURRENT_SETTINGS, _
                    "ptr", DllStructGetPtr($dm))
            $MonitorPos[$id][0] = DllStructGetData($dm, 7, 1)
            $MonitorPos[$id][1] = DllStructGetData($dm, 7, 2)
            $MonitorPos[$id][2] = DllStructGetData($dm, 18)
            $MonitorPos[$id][3] = DllStructGetData($dm, 19)
            $msg &= "Monitor " & ($id) & " start point:(" &  _
                DllStructGetData($dm, 7, 1) & "," & _
                DllStructGetData($dm, 7, 2) & ") " & @TAB & "Screen resolution: " & _
                DllStructGetData($dm, 18) & "x" & _
                DllStructGetData($dm, 19) & @LF
        EndIf
        $dev += 1
    Until $EnumDisplays[0] = 0

    $MonitorPos[0][0] = $id
    DllClose($dll)

    MsgBox(0,"Screen Info",$msg)
    return MonitorPos

EndFunc
Edited by Yibing
Link to comment
Share on other sites

Sorry, I made some changes but didn't do further testing. Now the working code:

I've Win98 SE with a Radeon Series 7000 working at 1280 x 768 and the program says

"Screen Resolution 83886080x50331648" (1280 * 65536 x 768 * 65536 !! ).

I just have to divide by 65536 or there's somewhere something wrong?

The program from the beta help (with the beta version, of course) also gives me... nothing;

it seems _WinAPI_EnumDisplayDevices("", $i) fails.

Any help? Thank you very much.

J.

Link to comment
Share on other sites

I've Win98 SE with a Radeon Series 7000 working at 1280 x 768 and the program says

"Screen Resolution 83886080x50331648" (1280 * 65536 x 768 * 65536 !! ).

I just have to divide by 65536 or there's somewhere something wrong?

The program from the beta help (with the beta version, of course) also gives me... nothing;

it seems _WinAPI_EnumDisplayDevices("", $i) fails.

Any help? Thank you very much.

J.

The following code works well for me. Also, I'm failing to see mention of _WinAPI_EnumDisplayDevices in this script. If you are having trouble with the function, and it is not a part of this UDF, rather a part of your own script, Please post in the correct forum (General Help and Support)

;modified by Yibing
;Last modified Feb 15, 2008
MonitoInfo()

Func MonitoInfo()
    Const $DISPLAY_DEVICE_MIRRORING_DRIVER    = 0x00000008
    Const $ENUM_CURRENT_SETTINGS = -1
    Const $DISPLAY_DEVICE = "int;char[32];char[128];int;char[128];char[128]"
    Const $DEVMODE = "byte[32];short;short;short;short;int;int[2];int;int" & _
                    ";short;short;short;short;short;byte[32]" & _
                    ";short;ushort;int;int;int;int"
                    
    Dim $MonitorPos[1][4]
    $dev = 0
    $id = 0
    $dll = DllOpen("user32.dll")
    $msg = ""

    Dim $dd = DllStructCreate($DISPLAY_DEVICE)
    DllStructSetData($dd, 1, DllStructGetSize($dd))

    Dim $dm = DllStructCreate($DEVMODE)
    DllStructSetData($dm, 4, DllStructGetSize($dm))

    Do
        $EnumDisplays = DllCall($dll, "int", "EnumDisplayDevices", _
                "ptr", "NULL", _
                "int", $dev, _
                "ptr", DllStructGetPtr($dd), _
                "int", 0)
        $StateFlag = Number(StringMid(Hex(DllStructGetData($dd, 4)), 3))
        If ($StateFlag <> $DISPLAY_DEVICE_MIRRORING_DRIVER) And ($StateFlag <> 0) Then;ignore virtual mirror displays
            $id += 1
            ReDim $MonitorPos[$id+1][5]
            $EnumDisplaysEx = DllCall($dll, "int", "EnumDisplaySettings", _
                    "str", DllStructGetData($dd, 2), _
                    "int", $ENUM_CURRENT_SETTINGS, _
                    "ptr", DllStructGetPtr($dm))
            $MonitorPos[$id][0] = DllStructGetData($dm, 7, 1)
            $MonitorPos[$id][1] = DllStructGetData($dm, 7, 2)
            $MonitorPos[$id][2] = DllStructGetData($dm, 18)
            $MonitorPos[$id][3] = DllStructGetData($dm, 19)
            $msg &= "Monitor " & ($id) & " start point:(" &  _
                DllStructGetData($dm, 7, 1) & "," & _
                DllStructGetData($dm, 7, 2) & ") " & @TAB & "Screen resolution: " & _
                DllStructGetData($dm, 18) & "x" & _
                DllStructGetData($dm, 19) & @LF
        EndIf
        $dev += 1
    Until $EnumDisplays[0] = 0

    $MonitorPos[0][0] = $id
    DllClose($dll)

    MsgBox(0,"Screen Info",$msg)
    return $MonitorPos

EndFunc

Cheers

Brett

:)

Link to comment
Share on other sites

  • 2 months later...

Does anyone know how to modify the code from the first post to retreive an array of supported resolutions rather than the current display?

This is for my simple SetResolution app: http://www.boot-land.net/forums/?showtopic=2897

At the moment I'm just using rescopy.exe from here http://www.naughter.com/qres.html and parsing its output. However, under someone wants to use SetResolution under 64bit and rescopy doesn't function under 64bit.

I realise a call to WMI will work (and it does as I've tried). But the problem there is that a call to WMI for supported resolutions doesn't work properly under PE. EnumDisplaySettingsEx is the way to go, but it is quite complex to say the least!

Regards,

Galapo.

Link to comment
Share on other sites

There's possible code from here which could be ported: http://www.boot-land.net/forums/index.php?...ost&p=34246

DEVMODE mode;
      ZeroMemory(&mode, sizeof(DEVMODE));
      mode.dmSize = sizeof(DEVMODE);
      mode.dmDriverExtra = 0;
      if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode))
      {
          _tprintf(_T("\nCurrent: h%u v%u b%u f%u\n"), mode.dmPelsWidth, mode.dmPelsHeight, mode.dmBitsPerPel, mode.dmDisplayFrequency);
      }
      _tprintf("Supported modes:\n");
      for(DWORD index = 0;;++index)
      {
           ZeroMemory(&mode, sizeof(DEVMODE));
           mode.dmSize = sizeof(DEVMODE);
           mode.dmDriverExtra = 0;
           DWORD res = EnumDisplaySettingsEx(NULL, index, &mode, 0 );
           if (!res) break;
           _tprintf(_T("h%u v%u b%u f%u\n"), mode.dmPelsWidth, mode.dmPelsHeight, mode.dmBitsPerPel, mode.dmDisplayFrequency);
      }

Regards,

Galapo.

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...