Подтвердить что ты не робот

Ошибка I2C при использовании функций конфигурации монитора Windows

Я пытаюсь получить/установить уровень яркости монитора через Windows API. Я пробовал как Функции настройки монитора низкого уровня, так и High- Настройки монитора уровня экрана, но оба они, кажется, ломаются в одном и том же месте. В обоих случаях у меня нет проблем с обработкой дескриптора HMONITOR и получением обработчика физического монитора из HMONITOR, но как только я попытаюсь запросить возможности DDC/CI, я получаю сообщение об ошибке "An error occurred while transmitting data to the device on the I2C bus."

Конкретными функциями, вызывающими эту ошибку, являются GetMonitorCapabilities для высокоуровневых функций и GetCapabilitiesStringLength для низкоуровневых функций. Они оба вызывают одну и ту же ошибку.

Это заставляет меня думать, что, возможно, мой монитор не поддерживает DDC/CI, но я знаю, что яркость монитора ноутбука можно изменить через панель управления, поэтому его нужно каким-то образом контролировать с помощью программного обеспечения. Также я могу успешно использовать классы WMI в PowerShell script, чтобы получить/установить яркость, как описано на странице this. Большинство вещей, которые я прочитал, показывают, что большинство современных экранов ноутбуков поддерживают DDC/CI.

Есть ли способ узнать, что вызывает эту ошибку, или получить дополнительную информацию об этом? Я в настоящее время работаю на С++ в Visual Studio 2013 в Windows 7. Возможно, я мог бы использовать 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 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 возвращается успешно. Любые мысли о том, почему это может быть?

4b9b3361

Ответ 1

Это проблема "неудобного оборудования", о шине I2C, о которой он говорит, является логическое соединение между видеоадаптером и монитором. В первую очередь полезно для подключения и воспроизведения. Базовый код ошибки - 0xC01E0582, STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA. Он генерируется вспомогательной функцией DxgkDdiI2CTransmitDataToDisplay() в драйвере мини-порта видео. Задача драйвера видео драйвера заключается в ее настройке, предоставляя функции, которые щекочут шину и реализуют IOCTL, лежащую в основе GetMonitorCapabilities().

Очевидно, что вы являетесь владельцем устройства, здесь нет ничего, что можно было бы сделать с этим сбоем в вашей программе на С++. Вы можете случайным образом открутить колесо фортуны, ища обновления драйвера от производителя видеоадаптера. Но отличные от нуля шансы на то, что монитор виноват здесь. Сначала попробуйте другой.

Ответ 2

Я знаю свое плохое время, чтобы ответить, но я думал, что вы должны знать.

Проблема, с которой вы сталкиваетесь, связана с отключением DDC/CI на вашем мониторе, поэтому вы должны перейти к настройкам монитора и проверить, отключен ли DDC/CI, и если это так, тогда вы должны включить его и запустить свой код еще раз. Это сработает. Если вы не смогли найти параметр DDC/CI (у некоторых мониторов есть отдельная кнопка для включения/выключения DDC/CI, так как монитор Benq T71W имеет отдельную кнопку со стрелкой вниз, чтобы включить/отключить DDC/CI), тогда вы должны обратитесь к руководству вашего монитора или обратитесь к производителю.

Надеюсь, что это поможет. и извините за поздний ответ.

Удачи.:)