package main
import (
"fmt"
"log"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// 定义 Windows API 所需的常量和结构
const (
MONITOR_DEFAULTTONULL = 0x00000000
MONITOR_DEFAULTTOPRIMARY = 0x00000001
MONITOR_DEFAULTTONEAREST = 0x00000002
MC_CAPS_HORIZONTAL_POSITION = 0x00000001
MC_CAPS_VERTICAL_POSITION = 0x00000002
MC_CAPS_BRIGHTNESS = 0x00000004
MC_CAPS_CONTRAST = 0x00000008
MC_CAPS_COLOR_PRESET = 0x00000010
MC_CAPS_RED_GREEN_BLUE_GAIN = 0x00000020
MC_CAPS_RED_GREEN_BLUE_DRIVE = 0x00000040
MC_CAPS_DEGAUSS = 0x00000080
MC_CAPS_RESTORE_FACTORY_DEFAULTS = 0x00000100
MC_CAPS_RESTORE_FACTORY_COLOR_DEFAULTS = 0x00000200
MC_CAPS_MONITOR_TECHNOLOGY_TYPE = 0x00000400
MC_CAPS_DISPLAY_AREA_SIZE = 0x00000800
)
// 定义 PHYSICAL_MONITOR 结构
type PHYSICAL_MONITOR struct {
hPhysicalMonitor windows.Handle
szPhysicalMonitorDescription [128]uint16
}
// 加载所需的 DLL 和函数
var (
dxva2 = windows.NewLazySystemDLL("dxva2.dll")
user32 = windows.NewLazySystemDLL("user32.dll")
// 显示设备枚举函数
procEnumDisplayMonitors = user32.NewProc("EnumDisplayMonitors")
procGetMonitorInfoW = user32.NewProc("GetMonitorInfoW")
procGetNumberOfPhysicalMonitorsFromHMONITOR = dxva2.NewProc("GetNumberOfPhysicalMonitorsFromHMONITOR")
procGetPhysicalMonitorsFromHMONITOR = dxva2.NewProc("GetPhysicalMonitorsFromHMONITOR")
procDestroyPhysicalMonitor = dxva2.NewProc("DestroyPhysicalMonitor")
// DDC/CI 控制函数
procGetMonitorCapabilities = dxva2.NewProc("GetMonitorCapabilities")
procGetMonitorBrightness = dxva2.NewProc("GetMonitorBrightness")
procSetMonitorBrightness = dxva2.NewProc("SetMonitorBrightness")
)
type HMONITOR uintptr
type HDC uintptr
// 回调函数类型,用于 EnumDisplayMonitors
type MonitorEnumProc func(hMonitor HMONITOR, hdcMonitor HDC, lprcMonitor *RECT, dwData uintptr) uintptr
// RECT 结构定义
type RECT struct {
Left int32
Top int32
Right int32
Bottom int32
}
// 枚举所有显示器并设置亮度
func SetBrightnessForAllMonitors(brightness uint32) error {
// 确保亮度值在有效范围内(0-100)
if brightness > 100 {
brightness = 100
} else if brightness < 0 {
brightness = 0
}
// 存储物理监视器的切片
var physicalMonitors []PHYSICAL_MONITOR
// 枚举显示器的回调函数
callback := func(hMonitor HMONITOR, hdcMonitor HDC, lprcMonitor *RECT, dwData uintptr) uintptr {
// 获取物理监视器数量
var monitorCount uint32
_, _, err := procGetNumberOfPhysicalMonitorsFromHMONITOR.Call(
uintptr(hMonitor),
uintptr(unsafe.Pointer(&monitorCount)))
if err != nil && err.(syscall.Errno) != 0 {
log.Printf("获取物理监视器数量失败: %v", err)
return 1 // 继续枚举其他显示器
}
// 分配物理监视器数组
monitors := make([]PHYSICAL_MONITOR, monitorCount)
_, _, err = procGetPhysicalMonitorsFromHMONITOR.Call(
uintptr(hMonitor),
uintptr(monitorCount),
uintptr(unsafe.Pointer(&monitors[0])))
if err != nil && err.(syscall.Errno) != 0 {
log.Printf("获取物理监视器信息失败: %v", err)
return 1 // 继续枚举其他显示器
}
// 添加到物理监视器列表
physicalMonitors = append(physicalMonitors, monitors...)
return 1 // 继续枚举其他显示器
}
// 枚举所有显示器
_, _, err := procEnumDisplayMonitors.Call(
0,
0,
uintptr(syscall.NewCallback(MonitorEnumProc(callback))),
0)
if err != nil && err.(syscall.Errno) != 0 {
return fmt.Errorf("枚举显示器失败: %v", err)
}
// 为每个物理监视器设置亮度
for _, monitor := range physicalMonitors {
// 获取显示器功能
var capabilities DWORD
var supportedColorTemperatures DWORD
_, _, err := procGetMonitorCapabilities.Call(
uintptr(monitor.hPhysicalMonitor),
uintptr(unsafe.Pointer(&capabilities)),
uintptr(unsafe.Pointer(&supportedColorTemperatures)))
if err != nil && err.(syscall.Errno) != 0 {
log.Printf("获取显示器功能失败: %v", err)
continue
}
// 检查显示器是否支持亮度调节
if capabilities&MC_CAPS_BRIGHTNESS == 0 {
log.Println("此显示器不支持亮度调节")
continue
}
// 获取当前亮度范围
var minimumBrightness, currentBrightness, maximumBrightness uint32
_, _, err = procGetMonitorBrightness.Call(
uintptr(monitor.hPhysicalMonitor),
uintptr(unsafe.Pointer(&minimumBrightness)),
uintptr(unsafe.Pointer(¤tBrightness)),
uintptr(unsafe.Pointer(&maximumBrightness)))
if err != nil && err.(syscall.Errno) != 0 {
log.Printf("获取亮度范围失败: %v", err)
continue
}
// 计算实际亮度值(将0-100映射到显示器的最小-最大范围)
actualBrightness := minimumBrightness + (brightness * (maximumBrightness - minimumBrightness) / 100)
// 设置亮度
_, _, err = procSetMonitorBrightness.Call(
uintptr(monitor.hPhysicalMonitor),
uintptr(actualBrightness))
if err != nil && err.(syscall.Errno) != 0 {
log.Printf("设置亮度失败: %v", err)
continue
}
fmt.Printf("成功将显示器 %s 的亮度设置为 %d%%\n",
windows.UTF16ToString(monitor.szPhysicalMonitorDescription[:]), brightness)
// 关闭物理监视器句柄
procDestroyPhysicalMonitor.Call(uintptr(monitor.hPhysicalMonitor))
}
return nil
}
// DWORD 类型定义
type DWORD uint32
func GetCurrentBrightnessForAllMonitors() error {
var physicalMonitors []PHYSICAL_MONITOR
callback := func(hMonitor HMONITOR, hdcMonitor HDC, lprcMonitor *RECT, dwData uintptr) uintptr {
var monitorCount uint32
_, _, err := procGetNumberOfPhysicalMonitorsFromHMONITOR.Call(
uintptr(hMonitor),
uintptr(unsafe.Pointer(&monitorCount)))
if err != nil && err.(syscall.Errno) != 0 {
log.Printf("获取物理监视器数量失败: %v", err)
return 1
}
monitors := make([]PHYSICAL_MONITOR, monitorCount)
_, _, err = procGetPhysicalMonitorsFromHMONITOR.Call(
uintptr(hMonitor),
uintptr(monitorCount),
uintptr(unsafe.Pointer(&monitors[0])))
if err != nil && err.(syscall.Errno) != 0 {
log.Printf("获取物理监视器信息失败: %v", err)
return 1
}
physicalMonitors = append(physicalMonitors, monitors...)
return 1
}
_, _, err := procEnumDisplayMonitors.Call(
0,
0,
uintptr(syscall.NewCallback(MonitorEnumProc(callback))),
0)
if err != nil && err.(syscall.Errno) != 0 {
return fmt.Errorf("枚举显示器失败: %v", err)
}
for _, monitor := range physicalMonitors {
var minimumBrightness, currentBrightness, maximumBrightness uint32
_, _, err := procGetMonitorBrightness.Call(
uintptr(monitor.hPhysicalMonitor),
uintptr(unsafe.Pointer(&minimumBrightness)),
uintptr(unsafe.Pointer(¤tBrightness)),
uintptr(unsafe.Pointer(&maximumBrightness)))
if err != nil && err.(syscall.Errno) != 0 {
log.Printf("获取亮度范围失败: %v", err)
continue
}
percent := 0
if maximumBrightness > minimumBrightness {
percent = int((currentBrightness - minimumBrightness) * 100 / (maximumBrightness - minimumBrightness))
}
fmt.Printf("显示器 %s 当前亮度为 %d%%(原始值: %d)\n",
windows.UTF16ToString(monitor.szPhysicalMonitorDescription[:]), percent, currentBrightness)
procDestroyPhysicalMonitor.Call(uintptr(monitor.hPhysicalMonitor))
}
return nil
}
func main() {
GetCurrentBrightnessForAllMonitors() // 获取当前亮度
// 设置亮度为 25%
err := SetBrightnessForAllMonitors(25)
if err != nil {
log.Fatalf("设置亮度时出错: %v", err)
}
}
(原) golang实现Win下的显示器亮度调整
原创文章,请
打赏后转载,并注明出处。
打赏后转载,并注明出处。