Sto tentando di ottenere/impostare il livello di luminosità del monitor tramite l'API di Windows. Ho provato sia il Low-Level Monitor Configuration Functions e il High-Level Monitor Configuration Functions, ma entrambi sembrano rompere nello stesso posto. In entrambi i casi non ho problemi a ottenere l'handle di HMONITOR e ad ottenere l'handle del monitor fisico da HMONITOR, ma quando provo a interrogare le funzionalità DDC/CI, viene visualizzato un errore "An error occurred while transmitting data to the device on the I2C bus.
"Errore I2C quando si utilizzano le funzioni di configurazione del monitor di Windows
Le funzioni particolari che causano questo errore è GetMonitorCapabilities per le funzioni di alto livello e GetCapabilitiesStringLength per le funzioni di basso livello. Entrambi causano lo stesso errore.
Questo mi porta a credere che forse il mio monitor non supporta DDC/CI, ma so che la luminosità del monitor del mio portatile può essere cambiata attraverso il pannello di controllo, quindi in qualche modo deve essere controllata tramite software. Inoltre, posso utilizzare correttamente le classi WMI in uno script PowerShell per ottenere/impostare la luminosità come descritto nella pagina this. La maggior parte delle cose che ho letto suggeriscono che la maggior parte dei moderni schermi per laptop supporta DDC/CI.
C'è un modo per scoprire che cosa sta causando questo errore o per ottenere ulteriori informazioni su di esso? Attualmente sto lavorando in C++ in Visual Studio 2013 su Windows 7. Potrei probabilmente usare WMI nel mio programma C++ se non riesco a far funzionare questo metodo corrente, ma ho pensato di chiederlo prima.
Ecco il codice ho attualmente:
#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;
}
Edit: Anche Vorrei sottolineare che physicalMonitors[0].hPhysicalMonitor
è 0, anche se il numero di monitor e descrizione del testo sono validi e la funzione GetPhysicalMonitorsFromHMONITOR
restituisce con successo. Qualche idea sul perché questo potrebbe essere?
Hai provato a chiamare direttamente GetMonitorBrightness/SetMonitorBrightness?Non hai assolutamente bisogno di richiedere le funzionalità –
Hai provato questo codice con lo stesso monitor su una scheda video diversa o con un monitor che sai funzionare tramite questa API? Il livello i2c viene gestito interamente dall'hardware sulla scheda che comunica attraverso l'interconnessione al monitor. È necessario che il driver supporti il passaggio dei comandi api al master i2c di bordo. A seconda della scheda, mfgr potrebbe essere stata implementata correttamente o meno. Nota: la certificazione WHQL richiede l'implementazione del passthrough I2C sul monitor. I tuoi dispositivi e driver sono certificati? – caskey