使用Windows Monitor API可以轻松实现。我不认为那里没有任何Python绑定,并且pywin32不包含那些函数。但是,使用
ctypes它们并不难。
这是一个将显示器切换至软关机然后再打开的示例。使其适应更改输入源等应该非常容易。毕竟,唯一复杂的部分是获取物理监视器的句柄:
from ctypes import windll, byref, Structure, WinError, POINTER, WINFUNCTYPEfrom ctypes.wintypes import BOOL, HMONITOR, HDC, RECT, LPARAM, DWORD, BYTE, WCHAR, HANDLE_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(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()def set_vcp_feature(monitor, pre, value): """Sends a DDC command to the specified monitor. See this link for a list of commands: ftp://ftp.cis.nctu.edu.tw/pub/csie/Software/X11/private/VeSaSpEcS/VESA_document_Center_Monitor_Interface/mccsV3.pdf """ if not windll.dxva2.SetVCPFeature(HANDLE(monitor), BYTE(pre), DWORd(value)): raise WinError()# Switch to SOFT-OFF, wait for the user to press return and then back to onfor handle in _iter_physical_monitors(): set_vcp_feature(handle, 0xd6, 0x04) raw_input() set_vcp_feature(handle, 0xd6, 0x01)


