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

标签 python windows api winapi ctypes

我正在使用 Python 制作 Night Light 应用程序。我正在使用 Windows API 来使用 Gamma Ramp 来完成我的任务。 我使用 user32.dll 中的 EnumDisplayDevicesW 获取连接到我的 PC 的显示器的信息和数量。

我的桌面上只连接了一台显示器,但输出给出了两台显示器的信息。

这是我的代码。我正在使用 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 是我的,但为什么需要第二个?

我拥有一台配备标准三星显示器的台式电脑。

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

最佳答案

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

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

根据 EnumDisplayDevicesW :

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

关于python - EnumDisplayDevices 提供两个显示器,即使我有一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65624377/

相关文章:

C4700 : uninitialized local variable when combining path

windows - 运行 robocopy bat 将整个驱动器复制到另一个驱动器

ios - 无法在第二个 View Controller 中更新我的 UIImage

javascript - Youtube API显示随机视频和缩略图

python - 无法通过 instabot 将一些照片上传到 instagram

Python pip 安装 mysql-connector-python 2.0.1 失败

python - 我如何编写一个 SQLAlchemy 查询来返回图中某个节点的所有后代?

python - Pip 在 Windows 7 中挂起

python - Elasticsearch python api GET 索引统计

java - 如何在 Java 中找到 MS Word 文档的页面大小、页面高度和宽度?