Jump to content

optain supported resolutions via EnumDisplaySettingsEx call


Recommended Posts

Looking back, I think I inadvertently posted a request in the wrong area here. Hopefully this is now in a more appropriate area. To repeat my request:

Does anyone know how to modify the monitor info code by fisofo to retreive an array of supported resolutions rather than the current display?

; 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

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 and parsing its output. However, 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!

There's possible code from here which could be ported:

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 and thanks for any help,

Galapo.

Link to comment
Share on other sites

Try this:

Global Const $EDS_RAWMODE = 0x2

Dim $DEVMODE, $DllRet, $enum = 0

$DEVMODE = DllStructCreate("char dmDeviceName[32];ushort dmSpecVersion;ushort dmDriverVersion;short dmSize;" & _
                           "ushort dmDriverExtra;dword dmFields;short dmOrientation;short dmPaperSize;short dmPaperLength;" & _
                           "short dmPaperWidth;short dmScale;short dmCopies;short dmDefaultSource;short dmPrintQuality;" & _
                           "short dmColor;short dmDuplex;short dmYResolution;short dmTTOption;short dmCollate;" & _
                           "byte dmFormName[32];dword dmBitsPerPel;int dmPelsWidth;dword dmPelsHeight;" & _
                           "dword dmDisplayFlags;dword dmDisplayFrequency")
    
DllStructSetData($DEVMODE, "dmSize", DllStructGetSize($DEVMODE))
    
Do
    $DllRet = DllCall("user32.dll", "int", "EnumDisplaySettingsEx", "ptr", 0, "dword", $enum, _
                      "ptr", DllStructGetPtr($DEVMODE), "dword", 0)
    $DllRet = $DllRet[0]
    
    $enum += 1
    
    ConsoleWrite("Width = " & DllStructGetData($DEVMODE, "dmPelsWidth") & " " & _
                 "Height = " & DllStructGetData($DEVMODE, "dmPelsHeight") & " " & _
                 "Bits = " & DllStructGetData($DEVMODE, "dmBitsPerPel") & " " & _
                 "Frequency = " & DllStructGetData($DEVMODE, "dmDisplayFrequency") & @LF)
Until $DllRet = 0

$DEVMODE = 0

MSDN

Link to comment
Share on other sites

A slight adjustment for my purposes:

Global Const $EDS_RAWMODE = 0x2

Dim $DEVMODE, $DllRet, $enum = 0

$DEVMODE = DllStructCreate("char dmDeviceName[32];ushort dmSpecVersion;ushort dmDriverVersion;short dmSize;" & _
                           "ushort dmDriverExtra;dword dmFields;short dmOrientation;short dmPaperSize;short dmPaperLength;" & _
                           "short dmPaperWidth;short dmScale;short dmCopies;short dmDefaultSource;short dmPrintQuality;" & _
                           "short dmColor;short dmDuplex;short dmYResolution;short dmTTOption;short dmCollate;" & _
                           "byte dmFormName[32];dword dmBitsPerPel;int dmPelsWidth;dword dmPelsHeight;" & _
                           "dword dmDisplayFlags;dword dmDisplayFrequency")
   
DllStructSetData($DEVMODE, "dmSize", DllStructGetSize($DEVMODE))
   
Do
    $DllRet = DllCall("user32.dll", "int", "EnumDisplaySettingsEx", "ptr", 0, "dword", $enum, _
                      "ptr", DllStructGetPtr($DEVMODE), "dword", 0)
    $DllRet = $DllRet[0]
   
    $enum += 1
   
    ConsoleWrite("Width = " & DllStructGetData($DEVMODE, "dmPelsWidth") / 65536 & " " & _
                 "Height = " & DllStructGetData($DEVMODE, "dmPelsHeight") / 65536  & " " & _
                 "Bits = " & DllStructGetData($DEVMODE, "dmBitsPerPel") / 65536  & " " & _
                 "Frequency = " & DllStructGetData($DEVMODE, "dmDisplayFrequency") / 65536  & @CRLF)
Until $DllRet = 0

$DEVMODE = 0

Thanks again for your help with this!

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...