目前,我正在使用此代码来获取显示亮度:
#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, ¤tBrightness, &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 一无所知,如果可能的话,还请提供其他信息/文档链接。预先感谢您。
我仍然无法让
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_
不起作用。枚举设备时返回的错误是“没有更多可用数据”。但我还是不明白为什么。