Baru-baru ini saya menemukan perangkat lunak ini: https://clickmonitorddc.bplaced.net/ Dan saya ingin menemukan cara untuk secara terprogram mengubah sumber input monitor default saya (dari DP ke HDMI dan kembali) (Pada monitor pertama dari dua monitor saya).

Saya menemukan ini Mengirim perintah DDC/CI untuk dipantau di Windows menggunakan Python? merinci cara mengirim perintah ddc-ci melalui python.

Sekarang ini semua baik dan bagus, tetapi file pdf yang ditautkan ke daftar perintah DDC telah kedaluwarsa dan sepertinya saya tidak tahu bagaimana saya akan menerapkan ini pada kasus khusus saya. Bermain-main hanya membuat saya berhasil membuat monitor saya menjadi kosong satu demi satu, tetapi bukan itu yang ingin saya capai.

Sayangnya saya tidak memiliki banyak upaya atau kode untuk membagikan bagian dari yang ada di posting tertaut di atas.

Bantuan apa pun akan sangat dihargai.

1
Tom 7 Maret 2020, 20:50

2 jawaban

Jawaban Terbaik

Setelah beberapa pengujian dengan kode yang ditautkan di asli saya, saya berhasil mengetahuinya:

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

Ternyata kode vcp untuk perintah input adalah 0x60, dan dari sana nilainya dapat ditentukan dengan cukup mudah, yaitu sebagai berikut:

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

4
Tom 18 Maret 2020, 21:31

Halaman ini mungkin memiliki informasi yang Anda cari. Tampaknya mirip dengan PDF yang tidak lagi ditautkan yang dirujuk dalam komentar: https://milek7.pl/ddcbacklight/mccs.pdf

-2
Jace 20 Agustus 2020, 15:18