开始

脚本位置点这里

ahk本身并未提供亮度控制的快捷api,但有以下三种方式可能实现:

  • 使用DllCall调用win32函数。
  • 使用ComObj调用cmd。
  • 使用Run调用cmd。

由于我没有找到合适的win32dll,最终是使用了后两种。两种方法各有优缺,下面我们来说说细节。

代码见最后一节

脚本是通过调用cmd来获取和设置屏幕亮度的,通过以下命令可以完成所需功能:

  • 设置
WMIC /NAMESPACE:\\root\wmi PATH WmiMonitorBrightnessMethods WHERE "Active=TRUE" CALL WmiSetBrightness Brightness=30 Timeout=0
  • 获取
WMIC /NAMESPACE:\\root\wmi PATH WmiMonitorBrightness WHERE "Active=TRUE" GET /value

注意: 这是cmd而不是powershell

有了cmd命令后,就可以使用AHK调用cmd,传递此命令行。

官网上有一个调用示例,使用的是下面的方法:

  • 使用com对象执行一条cmd。
  • 使用com对象执行多条cmd。
class ShellRun {
    static RunWaitOne(command) {
        shell := ComObject("WScript.Shell")
        exec := shell.Exec(A_ComSpec " /C " command)
        return exec.StdOut.ReadAll()
    }

    static RunWaitMany(commands) {
        shell := ComObject("WScript.Shell")
        exec := shell.Exec(A_ComSpec " /Q /K echo off")
        exec.StdIn.WriteLine(commands "`nexit")
        return exec.StdOut.ReadAll()
    }
}

来源:https://wyagd001.github.io/v2/docs/lib/Run.htm

但它的缺点是会出现cmd窗口的闪屏。
所以我们只适合使用它完成get任务,而set任务使用run更好。

但,还有一种方法不会出现cmd窗口:


RunCMD(CmdLine, WorkingDir := "", Codepage := "CP0", Fn := "RunCMD_Output", Slow := 1) {
  ; RunCMD v0.97 by SKAN on D34E/D67E
  ;            @ autohotkey.com/boards/viewtopic.php?t=74647
  ; Based on StdOutToVar.ahk by Sean
  ;            @ autohotkey.com/board/topic/15455-stdouttovar
  ; Modified by TAC109 to not use A_Args (disrupts Ahk2Exe)

  Slow := !!Slow, Fn := IsFunction(Fn) ? Fn : 0, P8 := (A_PtrSize = 8)
    , DllCall("CreatePipe", "ptr*", &hPipeR := 0, "ptr*", &hPipeW := 0, "Ptr", 0, "Int", 0)
    , DllCall("SetHandleInformation", "Ptr", hPipeW, "Int", 1, "Int", 1)
    , DllCall("SetNamedPipeHandleState", "Ptr", hPipeR, "UIntP", PIPE_NOWAIT := 1, "Ptr", 0, "Ptr", 0)
    , SI := Buffer(P8 ? 104 : 68, 0) ; STARTUPINFO structure
    , NumPut('uint', P8 ? 104 : 68, SI) ; size of STARTUPINFO
    , NumPut('uint', STARTF_USESTDHANDLES := 0x100, SI, P8 ? 60 : 44) ; dwFlags
    , NumPut('uint', hPipeW, SI, P8 ? 88 : 60) ; hStdOutput
    , NumPut('uint', hPipeW, SI, P8 ? 96 : 64) ; hStdError
    , PI := Buffer(P8 ? 24 : 16) ; PROCESS_INFORMATION structure

  If !DllCall("CreateProcess", "Ptr", 0, "Str", CmdLine, "Ptr", 0, "Int", 0, "Int", 1
    , "Int", 0x08000000 | DllCall("GetPriorityClass", "Ptr", -1, "UInt"), "Int", 0
    , "Ptr", WorkingDir ? StrPtr(WorkingDir) : 0, "Ptr", SI.Ptr, "Ptr", PI.Ptr)
    Return Format("{1:}", "", ErrorLevel := -1
      , DllCall("CloseHandle", "Ptr", hPipeW), DllCall("CloseHandle", "Ptr", hPipeR))


  DllCall("CloseHandle", "Ptr", hPipeW)
    , RnCMD := { PID: NumGet(PI, P8 ? 16 : 8, "UInt") }
    , File := FileOpen(hPipeR, "h", Codepage), LineNum := 1, sOutput := ""
  While (RnCMD.PID | DllCall("Sleep", "Int", Slow))
    and DllCall("PeekNamedPipe", "Ptr", hPipeR, "Ptr", 0, "Int", 0, "Ptr", 0
      , "Ptr", 0, "Ptr", 0)
    While RnCMD.PID and StrLen(Line := File.ReadLine())
      sOutput .= Fn ? Fn.Call(Line, LineNum++) : Line

  RnCMD.PID := 0, hProcess := NumGet(PI, 0, 'uint'), hThread := NumGet(PI, A_PtrSize, 'uint')
    , DllCall("GetExitCodeProcess", "Ptr", hProcess, "ptr*", &ExitCode := 0)
    , DllCall("CloseHandle", "Ptr", hProcess), DllCall("CloseHandle", "Ptr", hThread)
    , DllCall("CloseHandle", "Ptr", hPipeR), ErrorLevel := ExitCode
  Return sOutput
}

我们选择第一种,因为闪屏在整个脚本运行期间只会出现一次。

Run适合完成设置任务,比如将亮度设置为30:

Run(A_ComSpec ' /c "WMIC /NAMESPACE:\\root\wmi PATH WmiMonitorBrightnessMethods WHERE "Active=TRUE" CALL WmiSetBrightness Brightness=30 Timeout=0"', , 'Hide')

最后的参数Hide设定窗口为隐藏执行。

完整代码

此脚本位于仓库ahk-scripts/lightCtrl.ahk
仓库:https://gitee.com/dkwd/ahk-scripts.git

#Requires AutoHotkey v2.0

#Include G:\AHK\git-ahk-lib\Tip.ahk
#Include G:\AHK\git-ahk-lib\ShellRun.ahk

^Home:: LightCtrl.Set(LightCtrl.Inc)
^End:: LightCtrl.Set(LightCtrl.Desc)
^SC046:: LightCtrl.Set(LightCtrl.Toggle) ; ^scrollock

class LightCtrl {
  static cur := 0, low := 6, high := 30, inc := 0, desc := 1, toggle := 2

  static Get() {
    fields := ShellRun.RunWaitOne('WMIC /NAMESPACE:\\root\wmi PATH WmiMonitorBrightness WHERE "Active=TRUE" GET /value')
    return +Rtrim(SubStr(fields, InStr(fields, match := 'CurrentBrightness=') + StrLen(match), 2), '`r`n')
  }

  static Set(action, param := 2) {
    cur := this.cur || this.Get()
    switch action {
      case LightCtrl.Toggle: cur := _toggle()
      case LightCtrl.Inc: cur := _inc(param)
      case LightCtrl.Desc: cur := _desc(param)
      default: throw Error('unsupport action')
    }
    Run(A_ComSpec
      ' /c "WMIC /NAMESPACE:\\root\wmi PATH WmiMonitorBrightnessMethods WHERE "Active=TRUE" CALL WmiSetBrightness Brightness='
      cur ' Timeout=0"', , 'Hide')
    this.cur := cur, _showTip()

    _inc(val) => cur + val > 70 ? cur : cur + val
    _desc(val) => cur - val <= 0 ? cur : cur - val
    _toggle() => cur < 15 ? LightCtrl.high : LightCtrl.low

    _showTip() {
      dili := this.cur >= 10 ? '  ' : '   '
      raw := '+===+`n'
        . ' |' dili this.cur dili '|`n'
        . '+===+`n'
      Tip.ShowTip(raw)
    }
  }
}
posted on 2023-07-26 15:03  落寞的雪  阅读(393)  评论(0编辑  收藏  举报