2014-12-06 30 views
2

This page說:ctypes的:傳球和閱讀枚舉指針

枚舉類型未實現。你可以很容易地自己做, 使用c_int作爲基類。

如果很簡單,爲什麼不實施呢?例如,我如何get the current color temperature of my monitor

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. 

這是最接近我能得到:

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' 

...返回此:

65537 
65539 
<MyEnum object at 0x006F6DA0> 
<MyEnum object at 0x006F6DA0> 
<MyEnum object at 0x0234FAD0> 
0 
-1071241844 

這對無論是顯示器手柄相同。我究竟做錯了什麼?

回答

1

使用this answer,我莫名其妙地發現,它的工作原理使用None物理監視器句柄:

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' 

結果:

<MyEnum object at 0x005D6120> 
physical None 
6500K