You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Qt中实现多显示器亮度调节?两种尝试方案均遇阻

多显示器亮度调节方案求助(Qt新手)

我是Qt新手,想要开发一款可调节所有显示器亮度的程序,此前尝试了两种方案均存在问题:

  • 使用SetDeviceGammaRamp调整伽马值:该方案在单显示器或克隆模式多显示器下有效,但扩展模式下的多显示器无效果,即便获取了各显示器对应的HDC;
  • 使用IOCTL相关接口:仅对外部屏幕有效,笔记本屏幕无作用。

以下是尝试的代码:

第一段代码(SetDeviceGammaRamp实现)

BOOL CGammaRamp::SetBrightness(HDC hDC, WORD wBrightness)
{
    /*
    Changes the brightness of the entire screen.
    This function may not work properly in some video cards.

    The wBrightness value should be a number between 0 and 255.
    128 = Regular brightness
    above 128 = brighter
    below 128 = darker

    If hDC is NULL, SetBrightness automatically load and release
    the display device context for you.

    */
    BOOL bReturn = FALSE;
    HDC hGammaDC = hDC;

    //Load the display device context of the entire screen if hDC is NULL.
    if (hDC == NULL)
        hGammaDC = GetDC(NULL);

    if (hGammaDC != NULL)
    {
        //Generate the 256-colors array for the specified wBrightness value.
        WORD GammaArray[3][256];

        for (int iIndex = 0; iIndex < 256; iIndex++)
        {
            int iArrayValue = iIndex * (wBrightness + 128);

            if (iArrayValue > 65535)
                iArrayValue = 65535;

            GammaArray[0][iIndex] =
            GammaArray[1][iIndex] =
            GammaArray[2][iIndex] = (WORD)iArrayValue;

        }

        //Set the GammaArray values into the display device context.
        bReturn = SetDeviceGammaRamp(hGammaDC, GammaArray);
    }

    if (hDC == NULL)
        ReleaseDC(NULL, hGammaDC);

    return bReturn;
}

第二段代码(IOCTL接口实现)

#include "Ioctl.h"
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <iostream>
#include <Ntddvdeo.h>
#include "QDebug"

#define IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS  CTL_CODE(FILE_DEVICE_VIDEO, 0x125, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS    CTL_CODE(FILE_DEVICE_VIDEO, 0x126, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS      CTL_CODE(FILE_DEVICE_VIDEO, 0x127, METHOD_BUFFERED, FILE_ANY_ACCESS)

int Ioctl::setBrightness(int level)
{
    HANDLE h;
    DWORD nOutBufferSize = 256;
    BYTE SupportedBrightness[256];
    DWORD g_supportedLevelCount;
    DISPLAY_BRIGHTNESS DisplayBrightness;

    memset(SupportedBrightness, 0, sizeof(SupportedBrightness));

    /* use createfile function to open lcd.
    * url from microsoft about IOCTL code.
    */

    /*
    * char* 和 wchar_t* 互相转换参考博客
    */
    /*
    * c++代码参考博客
    */
    char temchar[] = "\\\\.\\LCD";
    char* szSour = temchar;
    WCHAR Temp[128] = { 0 };
    mbstowcs(Temp, szSour, strlen(szSour));
    h = CreateFileW(Temp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
    if (h == INVALID_HANDLE_VALUE) {
        qDebug()<<"Open \\\\.\\LCD error";
        exit(1);
    }

    /* Query for display supported level */
    if (!DeviceIoControl(h, IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS, NULL, 0, SupportedBrightness, nOutBufferSize, &g_supportedLevelCount, NULL)) {
        qDebug()<<"IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize;
        exit(1);
    }
    if (g_supportedLevelCount == 0)     /* 0 means not supported */
    {
        qDebug()<<"\nLCD not support LEVEL COUNT", g_supportedLevelCount;
        exit(1);
    }

    DisplayBrightness.ucDisplayPolicy = 0;
    DisplayBrightness.ucACBrightness = level;
    DisplayBrightness.ucDCBrightness = level;

    /* Set display backlight level */
    nOutBufferSize = sizeof(DisplayBrightness);
    if (!DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS, (DISPLAY_BRIGHTNESS*)&DisplayBrightness, nOutBufferSize, NULL, 0, &nOutBufferSize, NULL)) {
        qDebug()<<"IOCTL_VIDEO_SET_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize;
        exit(1);
    }

    Sleep(500); /* delay for some time while wmi event changed */
    nOutBufferSize = sizeof(DisplayBrightness);
    if (!DeviceIoControl(h, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS, NULL, 0, (DISPLAY_BRIGHTNESS*)&DisplayBrightness, nOutBufferSize, &nOutBufferSize, NULL)) {
        qDebug()<<"IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize;
        exit(1);
    }
    qDebug()<<"\nBrightness_AC: %d\nBrightness_DC: %d", DisplayBrightness.ucACBrightness, DisplayBrightness.ucDCBrightness;
}

恳请各位提供可行的解决方案,谢谢!

内容的提问来源于stack exchange,提问作者bully

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 00:42:48