使用 C++ WinAPI 在 Windows 10 上设置亮度

Setting brightness on Windows 10 using C++ WinAPI

我正在尝试在 Windows 10 机器上设置亮度。显示器似乎不支持 setMonitorBrightnesssetDeviceGammaRamp 会改变 gamma、白点等,所以我尽量不使用它。

我正在尝试使用 IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS 控件让它工作。当我使用 CreateFile() 获取监视器句柄时,我检查句柄是否无效并且没问题。但是当我用 IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS.

调用 DeviceIoControl() 时,我得到 ERROR_INVALID_HANDLE (错误 6)
typedef struct _DISPLAY_BRIGHTNESS {  
   UCHAR ucDisplayPolicy;  
   UCHAR ucACBrightness;  
   UCHAR ucDCBrightness;  
} DISPLAY_BRIGHTNESS, *PDISPLAY_BRIGHTNESS; 

DISPLAY_BRIGHTNESS _displayBrightness;

_displayBrightness.ucDisplayPolicy = 0;
_displayBrightness.ucACBrightness = 0;  //for testing purposes
_displayBrightness.ucDCBrightness = 0;

DWORD ret = NULL;
OVERLAPPED olp;

DWORD nOutBufferSize = sizeof(_displayBrightness);
HANDLE h = CreateFile(L"\\.\LCD",
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    OPEN_EXISTING,
    0, NULL);

if (h == INVALID_HANDLE_VALUE) {
    //Does not reach here
    return false;
}  

if (!DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS, (DISPLAY_BRIGHTNESS *)&_displayBrightness, nOutBufferSize, NULL, 0, &ret, &olp))
{
    // GetLastError() returns error code 6 - Invalid handle 
    return false;
} 

此外,我应该使用 CreateFile() 来获取监视器句柄,还是可以调用 MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY)

通话中

DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS,
                (DISPLAY_BRIGHTNESS*)&_displayBrightness, nOutBufferSize, NULL, 0, &ret,
                &olp)

&olp 指向未初始化的 OVERLAPPED 结构。该结构有一个事件对象句柄 (hEvent),它包含一个随机值。这是 DeviceIoControl 调用抱怨的无效句柄。

由于您没有使用 FILE_FLAG_OVERLAPPED 标志调用 CreateFile(无论如何这对于显示设备来说确实没有意义),因此您不需要传递 OVERLAPPED 结构。只需传递NULL,调用就会成功:

DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS,
                (DISPLAY_BRIGHTNESS*)&_displayBrightness, nOutBufferSize, NULL, 0, &ret,
                NULL)