我試圖通過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