2013-05-16 9 views
10

मैं अपने मॉनीटर को विंडोज (सामान्य स्रोत जैसे इनपुट स्रोत को बदलने) से नियंत्रित करना चाहता हूं, लेकिन पाइथन से डीडीसी/सीआई कमांड भेजने का कोई तरीका नहीं मिल रहा है ...पाइथन का उपयोग कर विंडोज़ पर निगरानी रखने के लिए डीडीसी/सीआई आदेश भेज रहा है?

लाइब्रेरी या विधि के बारे में कोई सुराग जो यहां मदद कर सकता है?

उत्तर

9

windows monitor API का उपयोग करके यह आसानी से संभव है। मुझे नहीं लगता कि वहां कोई पाइथन बाइंडिंग है और pywin32 में उन कार्यों को शामिल नहीं किया गया है। हालांकि, उन्हें कॉल करने के लिए ctypes का उपयोग करना मुश्किल नहीं है।

यहां एक उदाहरण है जो मॉनिटर को सॉफ्ट-ऑफ पर स्विच करता है और फिर वापस चालू करता है; इनपुट स्रोत को बदलने के लिए इसे अनुकूलित करना बहुत आसान होना चाहिए। केवल जटिल भाग भौतिक मॉनीटर के लिए हैंडल प्राप्त कर रहा है:

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) 
+0

उत्कृष्ट! यह अच्छी तरह से काम करता है, केवल तभी जब मेरा फिलिप्स मॉनीटर 0x60 कमांड को डिस्प्ले लिंक इनपुट के साथ समर्थन करेगा: / – ronszon

संबंधित मुद्दे