简体   繁体   English

EnumDisplayDevices 提供两个显示器,即使我有一个

[英]EnumDisplayDevices giving two Displays even though I have one

I was making an application for Night Light using Python.我正在使用 Python 为夜灯申请。 I'm using windows API for use of Gamma Ramp to accomplish my task.我正在使用 windows API 来使用 Gamma Ramp 来完成我的任务。 I used EnumDisplayDevicesW from user32.dll to get the information and number of displays connected to my PC.我使用来自user32.dllEnumDisplayDevicesW来获取连接到我的 PC 的显示器的信息和数量。

I have only one monitor connected to my desktop, but the output is giving information of two monitors.我只有一台显示器连接到我的桌面,但 output 提供两台显示器的信息。

Here's my code.这是我的代码。 I'm using Python and accessing WinAPI through ctypes module.我正在使用Python并通过ctypes模块访问 WinAPI 。

import ctypes
from ctypes import wintypes


class DISPLAY_DEVICEW(ctypes.Structure):
    _fields_ = [
        ('cb', wintypes.DWORD),
        ('DeviceName', wintypes.WCHAR * 32),
        ('DeviceString', wintypes.WCHAR * 128),
        ('StateFlags', wintypes.DWORD),
        ('DeviceID', wintypes.WCHAR * 128),
        ('DeviceKey', wintypes.WCHAR * 128)
    ]

if __name__ == '__main__':
    EnumDisplayDevices = ctypes.windll.user32.EnumDisplayDevicesW       # get the function address
    EnumDisplayDevices.restype = ctypes.c_bool                          # set return type to BOOL

    displays = []           # to store display information
    i = 0                   # iteration variable for 'iDevNum'

    while True:
        INFO = DISPLAY_DEVICEW()            # struct object
        INFO.cb = ctypes.sizeof(INFO)       # setting 'cnSize' prior to calling 'EnumDisplayDevicesW'

        if not EnumDisplayDevices(None, i, ctypes.byref(INFO), 0):
            break       # break as soon as False is returned by 'EnumDisplayDevices'

        displays.append(INFO)       # append information to the list
        i += 1

    # display information in a sequential form
    for x in displays:
        print('DeviceName:\t\t', x.DeviceName)
        print("DeviceString:\t", x.DeviceString)
        print("StateFlags:\t\t", x.StateFlags)
        print("DeviceID:\t\t", x.DeviceID)
        print("DeviceKey:\t\t", x.DeviceKey)
        print(), print()

And the output returned by the code is as follows:-而代码返回的output如下:-

DeviceName:      \\.\DISPLAY1
DeviceString:    Intel(R) HD Graphics 510
StateFlags:      5
DeviceID:        PCI\VEN_8086&DEV_1902&SUBSYS_D0001458&REV_06
DeviceKey:       \Registry\Machine\System\CurrentControlSet\Control\Video\{C31A4E45-2A30-11EB-953B-92862920CE33}\0000


DeviceName:      \\.\DISPLAY2
DeviceString:    Intel(R) HD Graphics 510
StateFlags:      0
DeviceID:        PCI\VEN_8086&DEV_1902&SUBSYS_D0001458&REV_06
DeviceKey:       \Registry\Machine\System\CurrentControlSet\Control\Video\{C31A4E45-2A30-11EB-953B-92862920CE33}\0001

As far as I know, the first one, ie, \\.\DISPLAY1 is mine one, but why there's a need for a second one??据我所知,第一个,即\\.\DISPLAY1是我的,但为什么需要第二个?

I own a Desktop PC with standard Samsung monitor.我拥有一台带有标准三星显示器的台式电脑。

Any help will be very helpful.任何帮助都会非常有帮助。 Thanks in advance!提前致谢!

I have only one monitor connected to my desktop, but the output is giving information of two monitors.我只有一台显示器连接到我的桌面,但 output 提供两台显示器的信息。

Running this code does not tell you that you have two "monitors", but two "adapters".运行此代码不会告诉您您有两个“监视器”,而是两个“适配器”。

According to EnumDisplayDevicesW :根据EnumDisplayDevicesW

To get information on the display adapter, call EnumDisplayDevices with lpDevice set to NULL.要获取有关显示适配器的信息,请调用 EnumDisplayDevices,并将 lpDevice 设置为 NULL。 For example, DISPLAY_DEVICE.DeviceString contains the adapter name.例如,DISPLAY_DEVICE.DeviceString 包含适配器名称。

To obtain information on a display monitor, first call EnumDisplayDevices with lpDevice set to NULL.要获取有关显示监视器的信息,首先调用 EnumDisplayDevices 并将 lpDevice 设置为 NULL。 Then call EnumDisplayDevices with lpDevice set to DISPLAY_DEVICE.DeviceName from the first call to EnumDisplayDevices and with iDevNum set to zero.然后调用 EnumDisplayDevices 并将 lpDevice 设置为 DISPLAY_DEVICE.DeviceName 从第一次调用 EnumDisplayDevices 并将 iDevNum 设置为零。 Then DISPLAY_DEVICE.DeviceString is the monitor name.然后 DISPLAY_DEVICE.DeviceString 是监视器名称。

So if you need to get the monitor information, you need to call:所以如果需要获取监控信息,需要调用:

EnumDisplayDevices(INFO.DeviceName,j,ctypes.byref(Monitor_INFO),0):

Here is a sample:这是一个示例:

import ctypes
from ctypes import wintypes


class DISPLAY_DEVICEW(ctypes.Structure):
    _fields_ = [
        ('cb', wintypes.DWORD),
        ('DeviceName', wintypes.WCHAR * 32),
        ('DeviceString', wintypes.WCHAR * 128),
        ('StateFlags', wintypes.DWORD),
        ('DeviceID', wintypes.WCHAR * 128),
        ('DeviceKey', wintypes.WCHAR * 128)
    ]

if __name__ == '__main__':
    EnumDisplayDevices = ctypes.windll.user32.EnumDisplayDevicesW       # get the function address
    EnumDisplayDevices.restype = ctypes.c_bool                          # set return type to BOOL

    displays = []           # to store display information
    i = 0                   # iteration variable for 'iDevNum'
    j = 0
    while True:
        INFO = DISPLAY_DEVICEW()            # struct object
        INFO.cb = ctypes.sizeof(INFO)       # setting 'cnSize' prior to calling 'EnumDisplayDevicesW'
        Monitor_INFO = DISPLAY_DEVICEW()   
        Monitor_INFO.cb = ctypes.sizeof(Monitor_INFO)  
        if not EnumDisplayDevices(None, i, ctypes.byref(INFO), 0):
            break       # break as soon as False is returned by 'EnumDisplayDevices'
        #j = 0
        while EnumDisplayDevices(INFO.DeviceName,j,ctypes.byref(Monitor_INFO),0):
            print("monitor name:\t\t",Monitor_INFO.DeviceName,'\n\n')
            j+=1

        displays.append(INFO)       # append information to the list
        i += 1

    # display information in a sequential form
    for x in displays:
        print('DeviceName:\t\t', x.DeviceName)
        print("DeviceString:\t", x.DeviceString)
        print("StateFlags:\t\t", x.StateFlags)
        print("DeviceID:\t\t", x.DeviceID)
        print("DeviceKey:\t\t", x.DeviceKey)
        print(), print()

So, after doing required changes, following is the final code to get all the display monitors connected to all the display adapters.因此,在进行必要的更改后,以下是使所有显示监视器连接到所有显示适配器的最终代码。

import ctypes
from ctypes import wintypes


class DISPLAY_DEVICEW(ctypes.Structure):
    _fields_ = [
        ('cb', wintypes.DWORD),
        ('DeviceName', wintypes.WCHAR * 32),
        ('DeviceString', wintypes.WCHAR * 128),
        ('StateFlags', wintypes.DWORD),
        ('DeviceID', wintypes.WCHAR * 128),
        ('DeviceKey', wintypes.WCHAR * 128)
    ]

if __name__ == '__main__':
    EnumDisplayDevices = ctypes.windll.user32.EnumDisplayDevicesW       # get the function address
    EnumDisplayDevices.restype = ctypes.c_bool                          # set return type to BOOL

    """    
    the following list 'displays', stores display adapter info in the following Structure:
    
        'List containing Tuple of displayAdapterInfo and list of monitorInfo controlled by the adapter'
        [
            (dispAdapterInfo1, [Monitor1, Monitor2, . . . ]), 
            (dispAdapterInfo2, [Monitor1, Monitor2, . . . ]), 
            . . . .
        ]
        
        Number of dispAdapter depends on the graphics driver, and number of Monitors per adapter depends on 
        number of monitors connected and controlled by adapter.
    """
    displays = []

    i = 0                   # iteration variable for 'iDevNum'
    while True:
        DISP_INFO = DISPLAY_DEVICEW()               # struct object for adapter info
        DISP_INFO.cb = ctypes.sizeof(DISP_INFO)     # setting 'cb' prior to calling 'EnumDisplayDevicesW'

        if not EnumDisplayDevices(None, i, ctypes.byref(DISP_INFO), 0):
            break       # break as soon as False is returned by 'EnumDisplayDevices'

        monitors = []       # stores list of monitors per adapter
        j = 0
        while True:
            MONITR_INFO = DISPLAY_DEVICEW()              # struct object for Monitor info
            MONITR_INFO.cb = ctypes.sizeof(MONITR_INFO)  # setting 'cb' prior to calling 'EnumDisplayDevicesW'

            if not EnumDisplayDevices(DISP_INFO.DeviceName, j, ctypes.byref(MONITR_INFO), 0):
                break  # break as soon as False is returned by 'EnumDisplayDevices'

            monitors.append(MONITR_INFO)
            j += 1

        displays.append((DISP_INFO, monitors))      # add the tuple (dispAdapterInfo, [MonitorsInfo])
        i += 1


    for display in displays:
        if display[1]:      # filter out the adapter with no monitor connected, i.e, empty list
            print("Adapter object:", display[0])
            print("List of Monitor objects :", display[1])
            print()

Now, display[0] is the adapter object, and can be used to get the information by referring the above DISPLAY_DEVICEW class, and display[1] is the list of monitors, which can be iterated over to get the objects of the monitor info, and get the information about it by referring DISPLAY_DEVICEW class.现在display[0]是适配器object,可以参考上面的DISPLAY_DEVICEW class来获取信息,display[1]是监视器列表,可以迭代得到监视器信息的对象,并通过参考DISPLAY_DEVICEW class获取相关信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 即使我创建了两个单独的列表,为什么if条件为真 - Even though I have created two seperate lists, why is the if condition true 我想将数据框附加到另一个数据框,即使它们的大小不同 - I want to append a dataframe to another one, even though they do not have the same size virtualenv:权限被拒绝错误,即使我有符号链接 - virtualenv: permission denied error even though i have symlink ZeroDivisionError:即使我有一个零捕手浮点除以零 - ZeroDivisionError: float division by zero even though I have a zero catcher ModuleNotFoundError: 没有名为 'imutils' 的模块。 即使我已经安装了 imutils - ModuleNotFoundError: No module named 'imutils' . even though I have install imutils 即使我有条件,为什么我的点会进入墙上? - Why are my dots going into the wall even though I have a condition? 即使我有最新的 PyAudio,PyAudio 也会出错 - Getting error with PyAudio even though I have the latest PyAudio 即使我安装了库,也无法导入 python 中的库 - Unable to import libraries in python even though i have the libraries installed 图书馆不在Pycharm中,即使我已经安装了它 - Library is not in Pycharm, even though i have already installed it “没有名为 pefile 的模块”即使我已经安装了 pefile - "No module named pefile" even though I have installed pefile
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM