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

2024-06-26 03:56:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用Python制作一个夜光应用程序。我正在使用windows API使用Gamma Ramp来完成我的任务。 我使用user32.dll中的EnumDisplayDevicesW获取连接到我的电脑的显示器的信息和数量

我只有一个显示器连接到我的桌面,但输出提供了两个显示器的信息

这是我的密码。我正在使用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()

代码返回的输出如下:-

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

据我所知,第一个,即,\\.\DISPLAY1是我的,但为什么需要第二个呢

我有一台带标准三星显示器的台式电脑

任何帮助都会很有帮助。提前谢谢


Tags: toinfoctypes显示器printdeviceiddisplayswintypes
2条回答

I have only one monitor connected to my desktop, but the output is giving information of two monitors.

运行此代码不会告诉您有两个“监视器”,而是两个“适配器”

根据^{}

To get information on the display adapter, call EnumDisplayDevices with lpDevice set to NULL. For example, DISPLAY_DEVICE.DeviceString contains the adapter name.

To obtain information on a display monitor, first call EnumDisplayDevices with lpDevice set to NULL. Then call EnumDisplayDevices with lpDevice set to DISPLAY_DEVICE.DeviceName from the first call to EnumDisplayDevices and with iDevNum set to zero. Then DISPLAY_DEVICE.DeviceString is the monitor name.

因此,如果您需要获取监视器信息,您需要拨打:

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

以下是一个示例:

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()

因此,在进行必要的更改之后,下面是将所有显示监视器连接到所有显示适配器的最终代码

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()

现在,display[0]是适配器对象,可以通过引用上面的DISPLAY_DEVICEW类来获取信息,display[1]是监视器列表,可以迭代获取监视器信息的对象,并通过引用DISPLAY_DEVICEW类来获取关于它的信息

相关问题 更多 >