[英]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.dll的EnumDisplayDevicesW来获取连接到我的 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.