Jump to content

Manage monitors through DDC/CI channel using VCP commands

Recommended Posts

In this thread it was mentioned how a software could manage single/multiple monitors.  I was curious to see how it could be possible to make it work without the tool.

So I made a script that change brightness (VCP 10) of my primary monitor for a few seconds. 

To learn about the VCP commands refer to https://milek7.pl/ddcbacklight/mccs.pdf

Among other commands, you can turn on/off (VCP D6) secondary monitor, change contrast (VCP 12), etc.  In the example you can see (and parse) all commands allowed by your monitor(s).

#include <String.au3>
#include <Array.au3>
#include <WinAPIGdi.au3>
#include <WinAPISysWin.au3>

Local $aPos, $aData = _WinAPI_EnumDisplayMonitors()

If IsArray($aData) Then
    ReDim $aData[$aData[0][0] + 1][5]
    For $i = 1 To $aData[0][0]
        $aPos = _WinAPI_GetPosFromRect($aData[$i][1])
        For $j = 0 To 3
            $aData[$i][$j + 1] = $aPos[$j]

_ArrayDisplay($aData, '_WinAPI_EnumDisplayMonitors')

Local $hWnd = _WinAPI_GetDesktopWindow()
ConsoleWrite($hWnd & @CRLF)
$hMonitor = _WinAPI_MonitorFromWindow($hWnd, $MONITOR_DEFAULTTONEAREST)
ConsoleWrite($hMonitor & @CRLF)

Local $aRet = DllCall("Dxva2.dll", "int", "GetNumberOfPhysicalMonitorsFromHMONITOR", "handle", $hMonitor, "int*", 0)
Local $iNumberMonitor = $aRet[2]
Const $tag_PHYSICAL_MONITOR = "handle hPhysicalMonitor; wchar strPhysicalMonitorDescription[128];"
Local $tPhysicalMonitor = DllStructCreate(_StringRepeat($tag_PHYSICAL_MONITOR, $iNumberMonitor))
$aRet = DllCall("Dxva2.dll", "int", "GetPhysicalMonitorsFromHMONITOR", "handle", $hMonitor, "int", $iNumberMonitor, "struct*", $tPhysicalMonitor)
MsgBox($MB_SYSTEMMODAL, "", $tPhysicalMonitor.strPhysicalMonitorDescription)

$aRet = DllCall("Dxva2.dll", "int", "GetCapabilitiesStringLength", "handle", $tPhysicalMonitor.hPhysicalMonitor, "int*", 0)
Local $iLength = $aRet[2] + 1
Local $tCapabilities = DllStructCreate("char sCapabilities[" & $iLength & "];")
$aRet = DllCall("Dxva2.dll", "int", "CapabilitiesRequestAndCapabilitiesReply", "handle", $tPhysicalMonitor.hPhysicalMonitor, _
  "ptr", DllStructGetPtr($tCapabilities), "int", $iLength)
ConsoleWrite($tCapabilities.sCapabilities & @CRLF)


$aRet = DllCall("Dxva2.dll", "int", "GetVCPFeatureAndVCPFeatureReply", "handle", $tPhysicalMonitor.hPhysicalMonitor, _
  "byte", 0x10, "int*", 0, "int*", 0, "int*", 0)
ConsoleWrite($aRet[3] = $MC_MOMENTARY ? "Momentary" : ($aRet[3] = $MC_SET_PARAMETER ? "Set" : "Unknown") & @CRLF)
ConsoleWrite("Current value = " & $aRet[4] & "/" & "Maximum = " & $aRet[5] & @CRLF)

Local $iCurrent = $aRet[4]
$aRet = DllCall("Dxva2.dll", "int", "SetVCPFeature", "handle", $tPhysicalMonitor.hPhysicalMonitor, _
  "byte", 0x10, "int", 20)
$aRet = DllCall("Dxva2.dll", "int", "SetVCPFeature", "handle", $tPhysicalMonitor.hPhysicalMonitor, _
  "byte", 0x10, "int", $iCurrent)

$aRet = DllCall("Dxva2.dll", "int", "DestroyPhysicalMonitors", "int", $iNumberMonitor, "ptr", DllStructGetPtr($tPhysicalMonitor))


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...