This page says:
Enumeration types are not implemented. You can do it easily yourself, using c_int as the base class.
If it were easy, why isn't it implemented yet? How do I get the current color temperature of my monitor, for instance?
BOOL GetMonitorColorTemperature(
_In_ HANDLE hMonitor,
_Out_ LPMC_COLOR_TEMPERATURE pctCurrentColorTemperature
);
Parameters
hMonitor [in]
Handle to a physical monitor. To get the monitor handle, call GetPhysicalMonitorsFromHMONITOR or GetPhysicalMonitorsFromIDirect3DDevice9.
pctCurrentColorTemperature [out]
Receives the monitor's current color temperature, specified as a member of the MC_COLOR_TEMPERATURE enumeration.
Return value
If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError.
This is the closest i was able to get:
from ctypes import *
import win32api # http://sourceforge.net/projects/pywin32/files/pywin32/
for idx, (hMon, hDC, (left, top, right, bottom)) in enumerate(win32api.EnumDisplayMonitors(None, None)):
print(hMon.handle) # or int(hMon)
class MyEnum(c_int):
MC_COLOR_TEMPERATURE_UNKNOWN = 0
MC_COLOR_TEMPERATURE_4000K = 1
MC_COLOR_TEMPERATURE_5000K = 2
MC_COLOR_TEMPERATURE_6500K = 3
MC_COLOR_TEMPERATURE_7500K = 4
MC_COLOR_TEMPERATURE_8200K = 5
MC_COLOR_TEMPERATURE_9300K = 6
MC_COLOR_TEMPERATURE_10000K = 7
MC_COLOR_TEMPERATURE_11500K = 8
o = MyEnum()
print(o)
po = pointer(o)
t = windll.dxva2.GetMonitorColorTemperature(hMon.handle, po) #byref(o))
#print(dir(o))
print(o)
print(po.contents)
print(t)
print(windll.kernel32.GetLastError()) # ERROR_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE = -1071241844 # Variable c_long '-0x03fd9da74'
...returns this:
65537
65539
<MyEnum object at 0x006F6DA0>
<MyEnum object at 0x006F6DA0>
<MyEnum object at 0x0234FAD0>
0
-1071241844
It's the same for either monitor handle. What am I doing wrong?
Using this answer, I somehow found out that it works using None
as physical monitor handle:
from ctypes import *
from ctypes.wintypes import BOOL, HMONITOR, HDC, RECT, LPARAM, DWORD, BYTE, WCHAR, HANDLE
import win32api # http://sourceforge.net/projects/pywin32/files/pywin32/
_MONITORENUMPROC = WINFUNCTYPE(BOOL, HMONITOR, HDC, POINTER(RECT), LPARAM)
class _PHYSICAL_MONITOR(Structure):
_fields_ = [('handle', HANDLE),
('description', WCHAR * 128)]
def _iter_physical_monitors(close_handles=True):
"""Iterates physical monitors.
The handles are closed automatically whenever the iterator is advanced.
This means that the iterator should always be fully exhausted!
If you want to keep handles e.g. because you need to store all of them and
use them later, set `close_handles` to False and close them manually."""
def callback(hmonitor, hdc, lprect, lparam):
monitors.append(hmonitor)
return True
monitors = []
if not windll.user32.EnumDisplayMonitors(None, None, _MONITORENUMPROC(callback), None):
raise WinError('EnumDisplayMonitors failed')
for monitor in monitors:
# Get physical monitor count
count = DWORD()
if not windll.dxva2.GetNumberOfPhysicalMonitorsFromHMONITOR(monitor, byref(count)):
raise WinError()
# Get physical monitor handles
physical_array = (_PHYSICAL_MONITOR * count.value)()
if not windll.dxva2.GetPhysicalMonitorsFromHMONITOR(monitor, count.value, physical_array):
raise WinError()
for physical in physical_array:
yield physical.handle
if close_handles:
if not windll.dxva2.DestroyPhysicalMonitor(physical.handle):
raise WinError()
mons = [m for m in _iter_physical_monitors(False)]
#for idx, (hMon, hDC, (left, top, right, bottom)) in enumerate(win32api.EnumDisplayMonitors(None, None)):
# print(hMon.handle) # or int(hMon)
temps = (
'UNKNOWN',
'4000K',
'5000K',
'6500K',
'7500K',
'8200K',
'9300K',
'10000K',
'11500K'
)
class MyEnum(c_int):
MC_COLOR_TEMPERATURE_UNKNOWN = 0
MC_COLOR_TEMPERATURE_4000K = 1
MC_COLOR_TEMPERATURE_5000K = 2
MC_COLOR_TEMPERATURE_6500K = 3
MC_COLOR_TEMPERATURE_7500K = 4
MC_COLOR_TEMPERATURE_8200K = 5
MC_COLOR_TEMPERATURE_9300K = 6
MC_COLOR_TEMPERATURE_10000K = 7
MC_COLOR_TEMPERATURE_11500K = 8
o = MyEnum()
print(o)
po = pointer(o)
pm = mons[0]
print("physical %r" % pm)
t = windll.dxva2.GetMonitorColorTemperature(pm, po) #byref(o))
if t:
#print(o)
#print(dir(po.contents))
print(temps[po.contents.value])
else:
print("Err: %s" % windll.kernel32.GetLastError()) # ERROR_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE = -1071241844 # Variable c_long '-0x03fd9da74'
Result:
<MyEnum object at 0x005D6120>
physical None
6500K