Results 1 to 7 of 7

Thread: What is an "Adapter" in EnumDisplayDevices

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2018
    Posts
    602

    What is an "Adapter" in EnumDisplayDevices

    I'm trying to understand the term adapter in the context of EnumDisplayDevices from
    https://docs.microsoft.com/en-us/win...isplaydevicesa

    To understand, I am trying to convert the example Microsoft code here
    https://docs.microsoft.com/en-us/win...isplay-monitor
    to VB

    Code:
    Option Explicit
    
    
    Private Declare Function EnumDisplayDevices Lib "User32" Alias "EnumDisplayDevicesA" _
        (Unused As Any, _
         ByVal iDevNum As Long, _
         lpDisplayDevice As DISPLAY_DEVICE, _
         ByVal dwFlags As Long) As Boolean
        
    Private Type DISPLAY_DEVICE
        cb As Long
        DeviceName As String * 32
        DeviceString As String * 128
        StateFlags As Long
        DeviceID As String * 128
        DeviceKey As String * 128
    End Type
    
    
    Private Sub Form_Load()
    
        'https://docs.microsoft.com/en-us/windows/win32/gdi/getting-information-on-a-display-monitor
    
        Dim DispDev As DISPLAY_DEVICE
        Dim nDeviceIndex As Long
        Dim Ret As Long
        Dim szSaveDeviceName As String * 32
    
        ' After the first call to EnumDisplayDevices,
        ' DispDev.DeviceString is the adapter name
        DispDev.cb = Len(DispDev)
        Ret = EnumDisplayDevices(ByVal 0&, nDeviceIndex, DispDev, ByVal 0&)
        szSaveDeviceName = ConvertAPIStringToVBString(DispDev.DeviceName)
        MsgBox szSaveDeviceName
        
        ' After second call, DispDev.DeviceString is the
        ' monitor name for that device
        DispDev.cb = Len(DispDev)
        'Ret = EnumDisplayDevices(DispDev.DeviceName, 0, DispDev, ByVal 0&)     'this call?
        Ret = EnumDisplayDevices(szSaveDeviceName, 0, DispDev, ByVal 0&)        'or this call?
        MsgBox ConvertAPIStringToVBString(DispDev.DeviceName)
        
    End Sub
    
    
    Private Function ConvertAPIStringToVBString(ByVal str As String) As String
    
        ConvertAPIStringToVBString = Left$(str, InStr(1, str, vbNullChar) - 1)
    
    End Function
    The second call to EnumDisplayDevices seems to fail.

    Is anyone able to spot my problem?

  2. #2
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: What is an "Adapter" in EnumDisplayDevices

    Failing how?

    One thing that jumps out is the name is in DeviceString,
    hr = StringCchCopy(lpszMonitorInfo, 129, DispDev.DeviceString);
    but you're just displaying the DeviceName again.

    Is that what you mean by failing?

  3. #3
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: What is an "Adapter" in EnumDisplayDevices

    A display adapter is a generally a video card. There are probably other things that could qualify as well, like virtual devices, but a physical video card is what is generally being referred to.

  4. #4

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2018
    Posts
    602

    Re: What is an "Adapter" in EnumDisplayDevices

    fafalone
    The first call returns \\.\DISPLAY1
    The second call returns nothing
    I've done exactly as the Microsoft example
    Code:
    1st call EnumDisplayDevices(NULL, nDeviceIndex, &DispDev, 0)
    2nd call EnumDisplayDevices(szSaveDeviceName, 0, &DispDev, 0)
    jmcilhinney
    Thank you

  5. #5

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2018
    Posts
    602

    Re: What is an "Adapter" in EnumDisplayDevices

    OK, so I came up with this and it seems to work.

    I don't trust it because I came up with it on my own,
    so if someone who really understands these things can look at it and comment, I would appreciate it.

    I don't think I am examining the flags properly in this line
    If ((DisplayDevice.StateFlags And DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) And _
    ((DisplayDevice.StateFlags And DISPLAY_DEVICE_ACTIVE) = DISPLAY_DEVICE_ACTIVE) Then


    Complete working code to enumerate monitors using EnumDisplayDevices
    Code:
    Option Explicit
    
    
    Const DISPLAY_DEVICE_ATTACHED_TO_DESKTOP = &H1
    Const DISPLAY_DEVICE_PRIMARY_DEVICE = &H4
    Const DISPLAY_DEVICE_MIRRORING_DRIVER = &H8
    
    Const DISPLAY_DEVICE_ACTIVE = &H1
    Const DISPLAY_DEVICE_ATTACHED = &H2
    
    Const EDD_GET_DEVICE_INTERFACE_NAME = &H1
    
    Private Type DisplayDevice
        cb As Long
        DeviceName As String * 32
        DeviceString As String * 128
        StateFlags As Long
        DeviceID As String * 128
        DeviceKey As String * 128
    End Type
    
    Private Declare Function EnumDisplayDevices Lib "User32" Alias "EnumDisplayDevicesA" _
        (ByVal lpDevice As String, _
         ByVal iDevNum As Long, _
         lpDisplayDevice As DisplayDevice, _
         ByVal dwFlags As Long) As Long
    
    
    Private Sub Command1_Click()
    
        ' Enumerate all Display Devices
        
        Dim DisplayDevice As DisplayDevice  'Display Device info
        Dim DisplayDeviceIndex As Long      'Display Device Index
        
        Dim MonitorDevice As DisplayDevice  'Monitor Device info
        Dim MonitorDeviceIndex As Long      'Monitor Device Index
        
        Dim Ret As Long
         
        'Initializations
        DisplayDevice.cb = Len(DisplayDevice)
        MonitorDevice.cb = Len(MonitorDevice)
        DisplayDeviceIndex = 0
        MonitorDeviceIndex = 0
        
        ' FIRST call to EnumDisplayDevices for info on display ADAPTER
        ' (lpDevice set to NULL)
        Do While EnumDisplayDevices(vbNullString, DisplayDeviceIndex, DisplayDevice, EDD_GET_DEVICE_INTERFACE_NAME) <> 0
    
            If ((DisplayDevice.StateFlags And DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) And _
                                                ((DisplayDevice.StateFlags And DISPLAY_DEVICE_ACTIVE) = DISPLAY_DEVICE_ACTIVE) Then
    
                ' SECOND call to EnumDisplayDevices for info on display MONITOR
                ' (lpDevice set to DISPLAY_DEVICE.DeviceName and iDevNum set to zero)
                Ret = EnumDisplayDevices(DisplayDevice.DeviceName, MonitorDeviceIndex, MonitorDevice, EDD_GET_DEVICE_INTERFACE_NAME)
    
                Debug.Print ConvertAPIStringToVBString(MonitorDevice.DeviceName) & "  " & ConvertAPIStringToVBString(MonitorDevice.DeviceID)
    
            End If
            
            Debug.Print DisplayDeviceIndex
            DisplayDeviceIndex = DisplayDeviceIndex + 1
    
        Loop
    
    End Sub
    
    
    Private Function ConvertAPIStringToVBString(ByVal str As String) As String
    
        ConvertAPIStringToVBString = Left$(str, InStr(1, str, vbNullChar) - 1)
    
    End Function

  6. #6
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: What is an "Adapter" in EnumDisplayDevices

    The difference I was referring to,

    The MSDN example reads DeviceName then DeviceString, two different members of the structure, your code is reading DeviceName after the 2nd call instead of DeviceString.

    So are you saying the second call returns nothing in the DeviceString?


    Code:
     if (EnumDisplayDevices(NULL, nDeviceIndex, &DispDev, 0)) 
            {  
                    hr = StringCchCopy(szSaveDeviceName, 33, DispDev.DeviceName);
                    if (FAILED(hr))
                    {
                    // TODO: write error handler 
                    }
            
            // After second call, DispDev.DeviceString is the  
            // monitor name for that device  
            EnumDisplayDevices(szSaveDeviceName, 0, &DispDev, 0);   
            
                    // In the following, lpszMonitorInfo must be 128 + 1 for  
                    // the null-terminator. 
                    hr = StringCchCopy(lpszMonitorInfo, 129, DispDev.DeviceString);
                    if (FAILED(hr))
                    {
                    // TODO: write error handler 
                    }
    Then your code,

    Code:
        Do While EnumDisplayDevices(vbNullString, DisplayDeviceIndex, DisplayDevice, EDD_GET_DEVICE_INTERFACE_NAME) <> 0
    
            If ((DisplayDevice.StateFlags And DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) And _
                                                ((DisplayDevice.StateFlags And DISPLAY_DEVICE_ACTIVE) = DISPLAY_DEVICE_ACTIVE) Then
    
                ' SECOND call to EnumDisplayDevices for info on display MONITOR
                ' (lpDevice set to DISPLAY_DEVICE.DeviceName and iDevNum set to zero)
                Ret = EnumDisplayDevices(DisplayDevice.DeviceName, MonitorDeviceIndex, MonitorDevice, EDD_GET_DEVICE_INTERFACE_NAME)
    
                Debug.Print ConvertAPIStringToVBString(MonitorDevice.DeviceName) & "  " & ConvertAPIStringToVBString(MonitorDevice.DeviceID)
    The name being blank in the 2nd call doesn't imply the string is blank, so I was asking if that was the issue.
    Last edited by fafalone; May 28th, 2022 at 04:19 AM.

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2018
    Posts
    602

    Re: What is an "Adapter" in EnumDisplayDevices

    Yes, I thought the 2nd MsgBox should also show something.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width