我试图通过Windows API获取/设置显示器的亮度级别。我已经尝试了Low-Level Monitor Configuration Functions和High-Level Monitor Configuration Functions,但他们似乎都在同一个地方。在这两种情况下,获取HMONITOR手柄并从HMONITOR获取物理监视器手柄都没有问题,但是一旦我尝试查询DDC/CI功能,就会看到一条错误消息:“An error occurred while transmitting data to the device on the I2C bus.
”使用Windows显示器配置功能时发生I2C错误
对于高级函数,此错误为GetMonitorCapabilities,对于低级函数为GetCapabilitiesStringLength。他们都造成相同的错误。
这使我相信,也许我的显示器不支持DDC/CI,但我知道我的笔记本电脑的显示屏亮度可以通过控制面板来改变,所以它必须通过某种方式的软件进行控制。另外,我可以在PowerShell脚本中成功使用WMI类来获取/设置this页面上描述的亮度。我读过的大部分内容都表明,大多数现代笔记本电脑屏幕都支持DDC/CI。
有什么方法可以找出是什么导致这个错误或获得更多关于它的信息?我目前在Windows 7的Visual Studio 2013中使用C++。如果我无法获取当前的方法,我可能会在我的C++程序中使用WMI,但我想我会先问这里。
这是我目前拥有的代码:
#include "stdafx.h"
#include <windows.h>
#include <highlevelmonitorconfigurationapi.h>
#include <lowlevelmonitorconfigurationapi.h>
#include <physicalmonitorenumerationapi.h>
#include <iostream>
#include <string>
int _tmain(int argc, _TCHAR* argv[])
{
DWORD minBrightness, curBrightness, maxBrightness;
HWND curWin = GetConsoleWindow();
if (curWin == NULL) {
std::cout << "Problem getting a handle to the window." << std::endl;
return 1;
}
// Call MonitorFromWindow to get the HMONITOR handle
HMONITOR curMon = MonitorFromWindow(curWin, MONITOR_DEFAULTTONULL);
if (curMon == NULL) {
std::cout << "Problem getting the display monitor" << std::endl;
return 1;
}
// Call GetNumberOfPhysicalMonitorsFromHMONITOR to get the needed array size
DWORD monitorCount;
if (!GetNumberOfPhysicalMonitorsFromHMONITOR(curMon, &monitorCount)) {
std::cout << "Problem getting the number of physical monitors" << std::endl;
return 1;
}
// Call GetPhysicalMonitorsFromHMONITOR to get a handle to the physical monitor
LPPHYSICAL_MONITOR physicalMonitors = (LPPHYSICAL_MONITOR)malloc(monitorCount*sizeof(PHYSICAL_MONITOR));
if (physicalMonitors == NULL) {
std::cout << "Unable to malloc the physical monitor array." << std::endl;
return 1;
}
if (!GetPhysicalMonitorsFromHMONITOR(curMon, monitorCount, physicalMonitors)) {
std::cout << "Problem getting the physical monitors." << std::endl;
return 1;
}
std::cout << "Num Monitors: " << monitorCount << std::endl; // This prints '1' as expected.
wprintf(L"%s\n", physicalMonitors[0].szPhysicalMonitorDescription); // This prints "Generic PnP Monitor" as expected
// Call GetMonitorCapabilities to find out which functions it supports
DWORD monCaps;
DWORD monColorTemps;
// The following function call fails with the error "An error occurred while transmitting data to the device on the I2C bus."
if (!GetMonitorCapabilities(physicalMonitors[0].hPhysicalMonitor, &monCaps, &monColorTemps)) {
std::cout << "Problem getting the monitor's capabilities." << std::endl;
DWORD errNum = GetLastError();
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
LPVOID buffer;
FormatMessage(flags, NULL, errNum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&buffer, 0, NULL);
wprintf(L"%s\n", buffer);
return 1;
}
// Same error when I use GetCapabilitiesStringLength(...) here.
// More code that is currently never reached...
return 0;
}
编辑:我也应该注意到,physicalMonitors[0].hPhysicalMonitor
为0,即使监视器数量和文字说明是有效的和GetPhysicalMonitorsFromHMONITOR
函数成功返回。任何想法为什么这可能是?
您是否尝试直接调用GetMonitorBrightness/SetMonitorBrightness?您并不一定需要查询功能 –
您是否曾尝试使用同一台显示器在不同视频卡上显示代码,或者您是否知道通过此api工作的显示器? i2c层完全由卡上的硬件通过与显示器的互连进行通信来处理。您需要驱动程序支持将api命令传递给板载i2c主设备。根据卡制造商这可能或可能没有正确实施。注意:WHQL认证要求对监视器实施I2C直通。您的设备和驱动程序已通过认证 – caskey