以编程方式更改监视器输入源

2024-06-16 08:29:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我最近偶然发现了这个软件:https://clickmonitorddc.bplaced.net/ 我想找到一种方法,以编程方式更改默认监视器的输入源(从DP到HDMI再到HDMI)(在两个监视器中的第一个监视器上)

我发现这个Sending DDC/CI commands to monitor on Windows using Python?详细介绍了如何通过python发送ddc ci命令

现在一切都很好,但是链接到DDC命令列表的pdf文件已经过期,我似乎不知道如何将其应用到我的具体案例中。胡闹只会让我成功地让我的显示器一个接一个地变成空白,但这并不是我真正想要实现的

遗憾的是,我没有太多的尝试或代码来分享上面链接帖子中的一部分

任何帮助都将不胜感激


Tags: 方法https命令net软件链接编程方式
2条回答

在使用我的原始文档中链接的代码进行了一些测试后,我终于找到了答案:

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 HDMI, wait for the user to press return and then back to DP
for handle in _iter_physical_monitors():
    set_vcp_feature(handle, 0x60, 0x11) #Change input to HDMI
    input()
    set_vcp_feature(handle, 0x60, 0x0F) #Change input to DisplayPort

输入命令的vcp代码是0x60,从那里可以很容易地确定值,如下所示:

0x01: D-sub/VGA, 0x03: DVI, 0x11 or 0x04 depending on the brand: HDMI, 0x0F: DisplayPort

此页面可能包含您要查找的信息。似乎与评论中引用的不再链接的PDF相似: https://milek7.pl/ddcbacklight/mccs.pdf

相关问题 更多 >