如何获取笔记本电脑显示屏亮度

问题描述 投票:0回答:1

目前,我正在使用此代码来获取显示亮度:

#include <iostream>
#include <Windows.h>
#include <physicalmonitorenumerationapi.h>
#include <highlevelmonitorconfigurationapi.h>

int main()
{
    HMONITOR monitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTONEAREST);
    DWORD numPhysicalMonitors;
    if (!GetNumberOfPhysicalMonitorsFromHMONITOR(monitor, &numPhysicalMonitors))
    {
        std::cerr << "Failed to get the number of physical monitors.\n";
        return 1;
    }

    PHYSICAL_MONITOR* physicalMonitors = new PHYSICAL_MONITOR[numPhysicalMonitors];
    if (!GetPhysicalMonitorsFromHMONITOR(monitor, numPhysicalMonitors, physicalMonitors))
    {
        std::cerr << "Failed to get physical monitors.\n";
        delete[] physicalMonitors;
        return 1;
    }

    for (DWORD i = 0; i < numPhysicalMonitors; i++)
    {
        DWORD minimumBrightness, currentBrightness, maximumBrightness;
        if (!GetMonitorBrightness(physicalMonitors[i].hPhysicalMonitor, &minimumBrightness, &currentBrightness, &maximumBrightness))
        {
            std::cerr << "Failed to get monitor brightness.\n";
            delete[] physicalMonitors;
            return 1;
        }

        std::cout << "Monitor " << i + 1 << ":\n"
            << "Minimum Brightness: " << minimumBrightness << "\n"
            << "Current Brightness: " << currentBrightness << "\n"
            << "Maximum Brightness: " << maximumBrightness << "\n";
    }

    delete[] physicalMonitors;
    return 0;
}

不幸的是,我对 WinAPI 一无所知。所有这些代码都是根据在 learn.microsoft.com 搜索“亮度”的结果组合在一起的,并点击相关函数的链接。

目前,我使用的是 AMD 芯片的联想笔记本电脑,配有 Nvidia 专用 GPU。显示模式设置为“仅限 Nvidia GPU”。也适用于 Windows 11。

虽然删除了监听能力部分,但它甚至无法获取监听能力(错误代码翻译为“在 I2C 总线上向设备传输数据时发生错误。”)

此代码是在 Visual Studio 2022 社区版、C++ 的 c++lastest 标准、x64 平台的调试配置中编译的。与 user32.lib、gdi32.lib、dxva2.lib 链接。

Windows SDK 版本 10.0。

(抱歉,我不知道哪些信息重要,所以我试图在这里转储尽可能多的东西)

我也尝试将显示模式改回Optimus,但没有成功。虽然在仅 GPU 模式下亮度控制栏呈灰色,但在 Optimus 下仍然正常。我仍然可以使用功能键(此型号为 Fn+F5/6)更改两种模式下的显示亮度

由于我对 WinAPI 一无所知,如果可能的话,还请提供其他信息/文档链接。预先感谢您。

c++ winapi visual-c++
1个回答
0
投票

我仍然无法让

GetMonitorBrightness
SetMonitorBrightness
工作。不过,我用
DeviceIoControl
想出了一个临时解决方案。虽然这个 IHMO 有点……不太干净。

再次强调,在我无意中陷入困境之前,我对 WinAPI 一无所知。请不要对我大喊大叫。

// Based on the example at learn.microsoft.com aka official documentations...
// Perhaps I could do better here? Anyways I'm happy because it works.
bool SetBrightness(HANDLE h, int brightness)
{
    if (brightness > 100)
        brightness = 100;
    if (brightness < 0)
        brightness = 0;
    DISPLAY_BRIGHTNESS DisplayBrightness = {
        .ucDisplayPolicy = DISPLAYPOLICY_BOTH,
        .ucACBrightness = (UCHAR)brightness,
        .ucDCBrightness = (UCHAR)brightness,
    };
    DWORD ret = NULL;
    DWORD nOutBufferSize = sizeof(DisplayBrightness);
    if (!DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS, (DISPLAY_BRIGHTNESS*)&DisplayBrightness, nOutBufferSize, NULL, 0, &ret, NULL))
        return false;
    return true;
}

取回东西几乎是一样的......

bool GetBrightness(HANDLE h, DISPLAY_BRIGHTNESS& DisplayBrightness)
{
    DWORD BytesReturned;
    // I thought these comments will help me to not get lost when looking at it in the future
    if (!DeviceIoControl(
        /*hDevice*/ h,
        /*dwIoControlCode*/ IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS,
        /*lpInBuffer*/ NULL, /*nInBufferSize*/ 0,
        /*lpOutBuffer*/ &DisplayBrightness, /*nOutBufferSize*/ sizeof(DISPLAY_BRIGHTNESS),
        /*lpBytesReturned*/ &BytesReturned,
        /*lpOverlapped*/ NULL))
        return false;
    return true;
}

关于获取

HANDLE
,呃...通过使用GUID(特别是
GUID_DEVINTERFACE_MONITOR
)打开所有监控设备(因为我不知道如何弄清楚哪个是真正重要的,哪个不是) t)

要实现此目的,我还必须安装 Windows 驱动程序工具包 (WDK)。

一个有点烦人的事情是设置亮度后应该有一点延迟才能获得亮度。实际上,我不确定这是否是一个轻微的延迟,或者你实际上必须做些什么,因为“延迟”我的意思是使用

std::cin
将一些输入输入到虚拟变量中。

使用这种方法后出现的另一个问题是

GUID_DEVCLASS_MONITOR
不起作用。但是
_DEVINTERFACE_
确实...所以如果您知道原因,也请解决它。谢谢你。

编辑1

我明白了为什么

_DEVCLASS_
不起作用。枚举设备时返回的错误是“没有更多可用数据”。但我还是不明白为什么。

© www.soinside.com 2019 - 2024. All rights reserved.