使用Windows监视器configurationfunction时发生I2C错误

我试图通过Windows API获取/设置显示器的亮度级别。 我已经尝试了低级监视器configuration函数和高级监视器configuration函数 ,但它们似乎都在同一个地方。 在这两种情况下,获取HMONITOR句柄并从HMONITOR获取物理监视器句柄都没有问题,但是一旦我尝试查询DDC / CIfunction,就会出现一个错误消息,提示“ An error occurred while transmitting data to the device on the I2C bus.

导致此错误的特定函数是高级函数的GetMonitorCapabilities和低级函数的GetCapabilitiesStringLength 。 他们都造成相同的错误。

这使我相信,也许我的显示器不支持DDC / CI,但我知道我的笔记本电脑的显示器亮度可以通过控制面板进行更改,所以它必须通过软件以某种方式控制。 另外,我可以在PowerShell脚本中成功使用WMI类来获取/设置本页所述的亮度。 我读过的大部分内容都表明,大多数现代笔记本电脑屏幕都支持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; } 

编辑:另外我应该注意,即使监视器计数和文本描述是有效的,并且GetPhysicalMonitorsFromHMONITOR函数成功返回, physicalMonitors[0].hPhysicalMonitor为0。 任何想法,为什么这可能是?

这是一个“不可靠的硬件”问题,它谈到的I2C总线是视频适配器和显示器之间的逻辑互连。 主要用于即插即用。 底层的错误代码是0xC01E0582,STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA。 它由视频微型端口驱动程序中的DxgkDdiI2CTransmitDataToDisplay()辅助函数生成。 这是供应商的视频驱动程序工作来配置它,提供令总线发痒的功能,并实现IOCTL底层的GetMonitorCapabilities()。

显然你是这里的设备驱动程序的土地,在你的C ++程序中没有任何事情可以做到这一点。 您可以通过从视频适配器制造商处寻找驱动程序更新来随机旋转命运。 但是显示器出现故障的可能性是非零的。 先试试另一个。

我知道它不好回复,但我想你应该知道。

您所面临的问题是由于您的显示器上禁用了D​​DC / CI,所以您应该转到显示器设置并检查DDC / CI是否被禁用,如果是,则必须启用它并再次运行您的代码。 这将工作。 如果您无法找到DDC / CI选项(某些显示器有启用/禁用DDC / CI的单独按钮,如Benq的T71W显示器有一个单独的向下箭头按钮来启用/禁用DDC / CI),那么您应该请参阅您的显示器说明书或联系制造商。

希望有所帮助。 并抱歉迟到的答复。

祝你好运。 🙂