Why GetMonitorBrightness function is returning false in the following code ?
-
I am creating an app in Qt5.7 MinGW in windows 7 32bit and i want the app to have a feature of changing screen brightness but when i call GetMonitorBrightness function its returning false and i don't know why please help me fix this problem.
My Header Files:
#include <windows.h> #include <highlevelmonitorconfigurationapi.h>
My Library Files:
I have copied the dxva2.dll and dxva2.lib files from "c:/windows/system32" to my project's Dll and Library folder respectively.
win32:CONFIG(release,debug|release): LIBS += -L&&PWD/Dll/ -ldxva2 win32:CONFIG(release, debug|release): LIBS += -L$$PWD/Library/ -ldxva2 else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/Library/ -ldxva2 else:unix: LIBS += -L$$PWD/Library/ -ldxva2 INCLUDEPATH += $$PWD/Library DEPENDPATH += $$PWD/Library
My Code:
I have created this "start caring" button which when clicked should change the screen brightness.
void EyeCare::on_startcaringButton_clicked() { HMONITOR monitorHandler = NULL ; LPDWORD minBrightnessLevel = NULL , maxBrightnessLevel = NULL, currentBrightnessLevel = NULL ; HWND windowHandler ; windowHandler = FindWindow(NULL,NULL) ; monitorHandler = MonitorFromWindow(windowHandler, MONITOR_DEFAULTTOPRIMARY) ; QString style = ui->startcaringButton->styleSheet() ; if (GetMonitorBrightness(monitorHandler,minBrightnessLevel, currentBrightnessLevel, maxBrightnessLevel) ){ DWORD newBrightnessLevel = (*maxBrightnessLevel) - 50 ; SetMonitorBrightness(monitorHandler,newBrightnessLevel) ; SaveCurrentMonitorSettings(monitorHandler) ; style.append("color: green ;") ; }else style.append("color: red ;") ; ui->startcaringButton->setStyleSheet (style) ; QErrorMessage *errorMessage = new QErrorMessage ; errorMessage->showMessage(GetLastErrorStdStr()); } QString GetLastErrorStdStr() { DWORD error = GetLastError(); if (error) { LPTSTR errorMessage; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,NULL, error,0,(LPWSTR) &errorMessage,0, NULL ); return QString :: fromWCharArray(errorMessage) ; } }
how can i make it work ??????????????????????????
-
Hi @Ahti,
A couple of things to consider:
- you're not checking if
FindWindow
failed. - you're not checking if
MonitorFromWindow
failed. - what did
GetLastErrorStdStr
actually return? (not even relevant until you've done #1 and #2 first). - which window are you expecting
FindWindow
to return a handle to? The result is probably not what you're expecting. How about using something like QWidget::winId() instead?
Cheers.
- you're not checking if
-
@Paul-Colby i used GetDesktopWindow() instead of FindWindow() and there is no need to check if GetDesktopWindow, FindWindow or MonitorFromWindow failed because all of them work with a desktop handler that is always there so they never fail that is why they have a return type as handler not bool.
-
@Ahti said in Why GetMonitorBrightness function is returning false in the following code ?:
so they never fail that is why they have a return type as handler not bool.
MSDN disagrees. It says for FindWindow's return type:
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
It also remarks about GetMonitorBrightness:
If this function is supported, the GetMonitorCapabilities function returns the MC_CAPS_BRIGHTNESS flag.
This function takes about 40 milliseconds to return.
The brightness setting is a continuous monitor setting. For more information, see Using the High-Level Monitor Configuration Functions.So have you checked the capabilities?
-
Hi,
your function is failing due to the monitor handle is not valid:hMonitor [in]
Handle to a physical monitor. To get the monitor handle, call GetPhysicalMonitorsFromHMONITOR or GetPhysicalMonitorsFromIDirect3DDevice9.
monitorHandler = MonitorFromWindow(windowHandler, MONITOR_DEFAULTTOPRIMARY) ; PHYSICAL_MONITOR realMonitorHandle; if (GetPhysicalMonitorsFromHMONITOR(monitorHandler,...) == true) GetMonitorBrightness(realMonitorHandle.hwnd,...);
You need to use above function to get a valid handle to the monitor.
This code is just pseudo-code so it can contain errors. -
It is not working because at least you have to respect the kind of parameters!
Please ready carefully the msdn...
GetPhysicalMonitorsFromHMONITOR as 3rd parameter wants a pointer to PHYSICAL_MONITOR
and GetMonitorBrightness wants a handle, that is: realMonitorHandle.hwnd -
@Ahti Why don't you read the documentation?
Here you can find this information https://msdn.microsoft.com/en-us/library/windows/desktop/dd692950(v=vs.85).aspx
pPhysicalMonitorArray [out]
Pointer to an array of PHYSICAL_MONITOR structures. The caller must allocate the array.You currently pass NULL! Check the above link - there is even an example.
-
now GetMonitorCapabilities is returning false.
My Code:
void EyeCare::on_startcaringButton_clicked() { QString style = ui->startcaringButton->styleSheet() ; HMONITOR monitorHandler = NULL ; DWORD minBrightnessLevel = 0, maxBrightnessLevel = 0, curBrightnessLevel = 0 ; HWND windowHandler ; DWORD numberOfMonitors = 1 ; LPPHYSICAL_MONITOR pointerToPhysicalMonitors = NULL ; windowHandler = GetDesktopWindow() ; // is equal to FindWindow(NULL,NULL) ; monitorHandler = MonitorFromWindow(windowHandler, MONITOR_DEFAULTTOPRIMARY) ; BOOL bSuccess = GetNumberOfPhysicalMonitorsFromHMONITOR(monitorHandler,&numberOfMonitors) ; if (bSuccess) { pointerToPhysicalMonitors = (LPPHYSICAL_MONITOR)malloc( numberOfMonitors* sizeof(PHYSICAL_MONITOR) ) ; if (pointerToPhysicalMonitors != NULL) { bSuccess = GetPhysicalMonitorsFromHMONITOR( monitorHandler,numberOfMonitors, pointerToPhysicalMonitors) ; LPDWORD MonitorCapabilities = NULL, SupportedColorTemperature = NULL; if (GetMonitorCapabilities(monitorHandler, MonitorCapabilities, SupportedColorTemperature)) { if (GetMonitorBrightness(windowHandler,&minBrightnessLevel, &curBrightnessLevel, &maxBrightnessLevel) ){ DWORD newBrightnessLevel = maxBrightnessLevel - 50 ; SetMonitorBrightness(monitorHandler,newBrightnessLevel) ; SaveCurrentMonitorSettings(monitorHandler) ; style.append("color: green ;") ; }else style.append("color: red ;") ; }else{ style.append("color: purple ;") ; } }else style.append("color: orange ;") ; }else style.append("color: yellow ;") ; ui->startcaringButton->setStyleSheet (style) ; }
-
@Ahti said in Why GetMonitorBrightness function is returning false in the following code ?:
LPDWORD MonitorCapabilities = NULL, SupportedColorTemperature = NULL;
if (GetMonitorCapabilities(monitorHandler, MonitorCapabilities, SupportedColorTemperature))
Shouldn't it be:
DWORD MonitorCapabilities = 0, SupportedColorTemperature = 0; if (GetMonitorCapabilities(monitorHandler, &MonitorCapabilities, &SupportedColorTemperature))
The documentation says: "To get extended error information, call GetLastError"
So, you should call GetLastError to see what went wrong. -
@Ahti
You should really understand that LPXXXX means pointer and is used when you pass a parameter to avoid that the object you are passing is copied by value (so all items inside in case of struct/class); passing a pointer only the address is copied in a new variable; that is:DWORD pdwMonitorCapabilities, pdwSupportedColorTemperatures; // a real allocated object or DWORD in this case GetMonitorCapabilities(monitorHandler, &pdwMonitorCapabilities, &pdwSupportedColorTemperatures) // address of allocated objects
If you pass a pointer sets to NULL, you are calling:
GetMonitorCapabilities(monitorHandler, NULL, NULL)
it is normal it returns FALSE because where should the funtion put the values you are asking for??
thus the function is not able to do the job it has been created for!!! -
This is what i get after using GetLastError function and fixing the bug in my code :
https://postimg.org/image/tq6eabl95/
why it says "invalid monitor handler was passed to it" even though i copied the code from the document ??
My Code:
void EyeCare::on_startcaringButton_clicked() { QString style = ui->startcaringButton->styleSheet() ; QLibrary userLib ("user32.dll") ; if ( userLib.load() ){ HMONITOR monitorHandler = NULL ; DWORD minBrightnessLevel = 0, maxBrightnessLevel = 0, curBrightnessLevel = 0 ; HWND windowHandler ; DWORD numberOfMonitors = 1 ; LPPHYSICAL_MONITOR pointerToPhysicalMonitors = NULL ; windowHandler = GetDesktopWindow() ; monitorHandler = MonitorFromWindow(windowHandler, MONITOR_DEFAULTTOPRIMARY) ; BOOL bSuccess = GetNumberOfPhysicalMonitorsFromHMONITOR(monitorHandler,&numberOfMonitors) ; if (bSuccess) { pointerToPhysicalMonitors = (LPPHYSICAL_MONITOR)malloc( numberOfMonitors* sizeof(PHYSICAL_MONITOR) ) ; if (pointerToPhysicalMonitors != NULL) { bSuccess = GetPhysicalMonitorsFromHMONITOR( monitorHandler,numberOfMonitors, pointerToPhysicalMonitors) ; DWORD MonitorCapabilities = 0, SupportedColorTemperature = 0 ; if (GetMonitorCapabilities(monitorHandler, &MonitorCapabilities, &SupportedColorTemperature)) { if (GetMonitorBrightness(windowHandler,&minBrightnessLevel, &curBrightnessLevel, &maxBrightnessLevel) ){ DWORD newBrightnessLevel = maxBrightnessLevel - 50 ; SetMonitorBrightness(monitorHandler,newBrightnessLevel) ; SaveCurrentMonitorSettings(monitorHandler) ; style.append("color: green ;") ; }else{ style.append("color: red ;") ; GetLastErrorString(TEXT("GetMonitorBrightness")) ; } }else{ style.append("color: purple ;") ; GetLastErrorString(TEXT("GetMonitorCapabilities")) ; } }else { style.append("color: orange ;") ; GetLastErrorString(TEXT("PhysicalMonitor")) ; } }else{ style.append("color: yellow ;") ; GetLastErrorString(TEXT("GetNumberOfPhysicalMonitorsFromHMONITOR")) ; } ui->startcaringButton->setStyleSheet (style) ; }else{ QErrorMessage *errorMessage = new QErrorMessage ; errorMessage->showMessage( userLib.errorString() ); } } void EyeCare::GetLastErrorString(LPTSTR lpszFunction) { LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message and exit the process lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); ExitProcess(dw); }
-
@Ahti said in Why GetMonitorBrightness function is returning false in the following code ?:
MonitorFromWindow
You should check what GetDesktopWindow and MonitorFromWindow returned.
-
I have fixed the invalid handle problem just like the person here did solved it
but now i get this error message :
https://postimg.org/image/y7gwif7r5/
and GetDesktopWindow never fails like the document says:
https://postimg.org/image/t2kslkg6t/
and for the MonitorFromWindow the document says it depends on the second parameter if you have only one monitor ( and that is what i have ). And it also says that if the second parameter is MONITOR_DEFAULTTOPRIMARY ( that is what i have set in the code ) it will return a handle to the primary display monitor.
so there is no need to check but i am still checking ( as you can see in the code )so the question is how can i fix that new error message i get (
https://postimg.org/image/y7gwif7r5/ ) ?My Code:
void EyeCare::on_startcaringButton_clicked() { QString style = ui->startcaringButton->styleSheet() ; QLibrary userLib ("user32.dll") ; if ( userLib.load() ){ HMONITOR monitorHandler = NULL ; DWORD minBrightnessLevel = 0, maxBrightnessLevel = 0, curBrightnessLevel = 0 ; HWND windowHandler ; DWORD numberOfMonitors = 1 ; LPPHYSICAL_MONITOR pointerToPhysicalMonitors = NULL ; windowHandler = GetDesktopWindow() ; monitorHandler = MonitorFromWindow(windowHandler, MONITOR_DEFAULTTOPRIMARY) ; if (monitorHandler == NULL) { QErrorMessage *showError = new QErrorMessage ; showError->showMessage("Failed to get the monitor handle!"); return ; }else { BOOL bSuccess = GetNumberOfPhysicalMonitorsFromHMONITOR(monitorHandler,&numberOfMonitors) ; if (bSuccess) { pointerToPhysicalMonitors = (LPPHYSICAL_MONITOR)malloc( numberOfMonitors* sizeof(PHYSICAL_MONITOR) ) ; if (pointerToPhysicalMonitors != NULL) { bSuccess = GetPhysicalMonitorsFromHMONITOR( monitorHandler,numberOfMonitors, pointerToPhysicalMonitors) ; HANDLE handle = pointerToPhysicalMonitors[0].hPhysicalMonitor ; DWORD MonitorCapabilities = 0, SupportedColorTemperature = 0 ; if (GetMonitorCapabilities(handle, &MonitorCapabilities, &SupportedColorTemperature)) { if (GetMonitorBrightness(handle,&minBrightnessLevel, &curBrightnessLevel, &maxBrightnessLevel) ){ DWORD newBrightnessLevel = maxBrightnessLevel - 50 ; SetMonitorBrightness(handle,newBrightnessLevel) ; SaveCurrentMonitorSettings(handle) ; style.append("color: green ;") ; }else{ style.append("color: red ;") ; GetLastErrorString(TEXT("GetMonitorBrightness")) ; } }else{ style.append("color: purple ;") ; GetLastErrorString(TEXT("GetMonitorCapabilities")) ; } }else { style.append("color: orange ;") ; GetLastErrorString(TEXT("PhysicalMonitor")) ; } }else{ style.append("color: yellow ;") ; GetLastErrorString(TEXT("GetNumberOfPhysicalMonitorsFromHMONITOR")) ; } ui->startcaringButton->setStyleSheet (style) ; } }else{ QErrorMessage *errorMessage = new QErrorMessage ; errorMessage->showMessage( userLib.errorString() ); } } void EyeCare::GetLastErrorString(LPTSTR lpszFunction) { LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message and exit the process lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); ExitProcess(dw); }