使用Python将DDC/CI命令发送到Windows上的监视器?

使用Python将DDC/CI命令发送到Windows上的监视器?,python,windows,screen,Python,Windows,Screen,我想让我的显示器从Windows控制(简单的事情,如更改输入源),但找不到从Python发送DDC/CI命令的方法 关于某个库或方法的任何线索可以在这里提供帮助吗?使用。我认为没有任何Python绑定,pywin32也不包含这些函数。然而,习惯于给他们打电话并不难 下面是一个将显示器切换为软关闭然后再打开的示例;它应该很容易适应改变输入源等。唯一复杂的部分是获取物理监视器的句柄毕竟: from ctypes import windll, byref, Structure, WinError, P

我想让我的显示器从Windows控制(简单的事情,如更改输入源),但找不到从Python发送DDC/CI命令的方法


关于某个库或方法的任何线索可以在这里提供帮助吗?

使用。我认为没有任何Python绑定,pywin32也不包含这些函数。然而,习惯于给他们打电话并不难

下面是一个将显示器切换为软关闭然后再打开的示例;它应该很容易适应改变输入源等。唯一复杂的部分是获取物理监视器的句柄毕竟:

from ctypes import windll, byref, Structure, WinError, POINTER, WINFUNCTYPE
from 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, code, 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(code), DWORD(value)):
        raise WinError()


# Switch to SOFT-OFF, wait for the user to press return and then back to ON
for handle in _iter_physical_monitors():
    set_vcp_feature(handle, 0xd6, 0x04)
    raw_input()
    set_vcp_feature(handle, 0xd6, 0x01)

杰出的只有当我的飞利浦显示器支持带有displaylink输入的0x60命令时,这项功能才能正常工作:/