none
How to control system brightness using windows api ? RRS feed

  • Question

  • Hi, I am working on an app in a c++ framework know as Qt. The app should be able to alter the system brightness but the problem is that I am not able to get the system brightness using windows api function GetMonitorBrightness() it returns 0.
    My code for getting system brightness with windows api:
       

    HWND win_handle = GetDesktopWindow();    HMONITOR monitor_handle = MonitorFromWindow(win_handle, MONITOR_DEFAULTTOPRIMARY);    DWORD num_of_monitors;    LPPHYSICAL_MONITOR physical_monitors_pointer;    BOOL num_physical_monitors_success, physical_monitors_success;    HANDLE handle;    LPDWORD min, max, cur;    if (monitor_handle != NULL){                num_physical_monitors_success = GetNumberOfPhysicalMonitorsFromHMONITOR(monitor_handle,&num_of_monitors);        if (num_physical_monitors_success){        physical_monitors_pointer = (LPPHYSICAL_MONITOR)malloc(                      num_of_monitors* sizeof(PHYSICAL_MONITOR));            if (physical_monitors_pointer != NULL)            physical_monitors_success = GetPhysicalMonitorsFromHMONITOR(monitor_handle,                                                          num_of_monitors,                                                         physical_monitors_pointer);               handle = physical_monitors_pointer[1].hPhysicalMonitor;        }    }

        // qDebug() is a function to display the result of variables   

    qDebug() << "win_handle: " << win_handle;    qDebug() << "monitor_handle: " << monitor_handle;    qDebug() << "num_of_monitors: " << num_of_monitors;    qDebug() << "num_physical_monitors_success: " << num_physical_monitors_success;    qDebug() << "physical_monitors_pointer: " << physical_monitors_pointer;    qDebug() << "physcical_monitors_success: " << physical_monitors_success;    qDebug() << "handle: " << handle;    qDebug() << "current brightness levels: " << GetMonitorBrightness(handle, min, cur, max);


    And this is the output:

       
    win_handle:  0x10010    
    monitor_handle:  0xaea01d7    
    num_of_monitors:  1    
    num_physical_monitors_success:  1
    physical_monitors_pointer:  0x3e26bb98    
    physcical_monitors_success:  1    
    handle:  0x0    
    current brightness levels:  0


    As you can see the GetMonitorBrightness() is returning 0 but why ?? please help 

    Edit:

    From what I can understand It has something to do with DDC/CI because i was working on this app in the past and it used to work on my old desktop maybe because i was able to enable and disable DDC/CI on the monitor itself by clicking on the button available on the monitor but I can't seem to find an option for DDC/CI in my new laptop.


    • Edited by _Ahtisham Sunday, May 26, 2019 5:01 AM edit
    Saturday, May 25, 2019 3:55 PM

All replies

  • The first monitor is 

    handle = physical_monitors_pointer[0].hPhysicalMonitor;

    The return value is a boolean :

    DWORD min, max, cur;
    BOOL bRet = GetMonitorBrightness(handle, &min, &cur, &max);


    • Edited by Castorix31 Saturday, May 25, 2019 4:49 PM
    Saturday, May 25, 2019 4:42 PM
  • Thanks for your reply. I changed to first monitor and renamed from LPDWORD to DWORD but still nothing its not working. Also I tried GetMonitorCapabilites() and it returned 0 so I ran GetLastError() after with FormatMessage() and it showed an error message  saying GetMonitorCapabilites() failed because invalid monitor handler was passed to it. 
    Saturday, May 25, 2019 4:58 PM
  • Thanks for your reply. I changed to first monitor and renamed from LPDWORD to DWORD but still nothing its not working.
    Assuming that GetPhysicalMonitorsFromHMONITOR succeeded and you made Castorix31's corrections then if GetMonitorBrightness failed call GetLastError immediately afterwards to find out why.
    Saturday, May 25, 2019 5:06 PM
  • Called GetLastError() immediately after GetMonitorBrightness() and I got this message:

    The operation completed successfully

    also i noticed if i call GetMonitorCapabilites() with monitor_handle i get invalid monitor handle passed error while as if i pass handle variable i get an error occurred while transmitting data to the device on the I2C bus



    • Edited by _Ahtisham Saturday, May 25, 2019 5:36 PM
    Saturday, May 25, 2019 5:34 PM
  • Called GetLastError() immediately after GetMonitorBrightness() and I got this message:

    The operation completed successfully

    Well, the only reason to call GetLastError is if GetMonitorBrightness failed.  Did it fail?
    Saturday, May 25, 2019 5:37 PM
  • I don't know because its contradicting. The documentation says GetMonitorBrightness return false if it fails and when I call GetLastError it returns 0 and a message saying "The operation completed successfully".
    Saturday, May 25, 2019 5:44 PM
  • You should do something like this -

    if(GetMonitorBrightness(handle, &min, &cur, &max))
    {
    // success! continue processing
    }
    else
    {
    DWORD err = GetLastError();
    // print err value
    }
    

    Saturday, May 25, 2019 5:49 PM
  • I did this:

    if(GetMonitorBrightness(handle, &min, &cur, &max))
        {
            qDebug() << "working..!";
        }
    else
        {
            DWORD err = GetLastError();
            qDebug() << "error occurred: " << err;
        }

    And this is what I got as output:

    error occurred:  3223725442


    Saturday, May 25, 2019 6:00 PM
  • It can also be done with VCP codes, but it will probably fail in your case... =>

    (with right handle)

    MC_VCP_CODE_TYPE pvct;
    DWORD dwMaximumValue = 0;
    DWORD wsVersion = 0;
    // 0xDF = Version
    BOOL bRet = GetVCPFeatureAndVCPFeatureReply(handle, 0xDF, &pvct, (LPDWORD)&wsVersion, &dwMaximumValue);
    if (!bRet)
    {
    	DWORD nError = GetLastError();
    	LPVOID lpMsgBuf = NULL;
    	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
    		NULL, nError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
    	if (lpMsgBuf != NULL)
    	{
    		WCHAR wsMessage[260] = L"";
    		swprintf(wsMessage, L"%s", lpMsgBuf);
    		MessageBox(NULL, wsMessage, L"Error", MB_OK | MB_ICONERROR);
    		LocalFree(lpMsgBuf);
    	}
    }
    else
    {
    	WCHAR wsMessage[260] = L"";
    	swprintf(wsMessage, L"VCP Version : %d", wsVersion);
    	MessageBox(NULL, wsMessage, L"Information", MB_OK | MB_ICONINFORMATION);
    }
    
    // 0x10 = Brightness
    DWORD dwCurrentValue = 0;
    bRet = GetVCPFeatureAndVCPFeatureReply(handle, 0x10, &pvct, (LPDWORD)&dwCurrentValue, &dwMaximumValue);
    if (!bRet)
    {
    	DWORD nError = GetLastError();
    	LPVOID lpMsgBuf = NULL;
    	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
    		NULL, nError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
    	if (lpMsgBuf != NULL)
    	{
    		WCHAR wsMessage[260] = L"";
    		swprintf(wsMessage, L"%s", lpMsgBuf);
    		MessageBox(NULL, wsMessage, L"Error", MB_OK | MB_ICONERROR);
    		LocalFree(lpMsgBuf);
    	}
    }
    else
    {
    	WCHAR wsMessage[260] = L"";
    	swprintf(wsMessage, L"Brightness : %d", dwCurrentValue);
    	MessageBox(NULL, wsMessage, L"Information", MB_OK | MB_ICONINFORMATION);
    }


    • Edited by Castorix31 Saturday, May 25, 2019 7:14 PM
    Saturday, May 25, 2019 7:13 PM
  • I did this:

    if(GetMonitorBrightness(handle, &min, &cur, &max))
        {
            qDebug() << "working..!";
        }
    else
        {
            DWORD err = GetLastError();
            qDebug() << "error occurred: " << err;
        }

    And this is what I got as output:

    error occurred:  3223725442


    Since 3223725442 is not a valid system error code (see System Error Codes) I can only speculate that something is wrong with code that we have not seen or something is wrong with your system.

    Saturday, May 25, 2019 8:02 PM
  • Since 3223725442 is not a valid system error code (see System Error Codes) I can only speculate that something is wrong with code that we have not seen or something is wrong with your system.

    It is apparently the code he talked about : Error 0xC0262582

    "an error occurred while transmitting data to the device on the I2C bus"

    Saturday, May 25, 2019 8:10 PM
  • Since 3223725442 is not a valid system error code (see System Error Codes) I can only speculate that something is wrong with code that we have not seen or something is wrong with your system.

    It is apparently the code he talked about : Error 0xC0262582

    "an error occurred while transmitting data to the device on the I2C bus"

    Interesting.
    Saturday, May 25, 2019 8:15 PM
  • GetMonitorBrightness and SetMonitorBrigthness are not always supported for any monitor.

    Can you control brightness of your monitor from Windows Action center?

    Try this program - will it work with your monitor?

    https://clickmonitorddc.bplaced.net/

     Documentation on SetMonitorBrigthness says: "If this function is supported, the GetMonitorCapabilities function returns the MC_CAPS_BRIGHTNESS flag."

    -- pa


    • Edited by Pavel A Saturday, May 25, 2019 11:56 PM
    Saturday, May 25, 2019 9:50 PM
  • >error occurred:  3223725442

    Which is: An error occurred while transmitting data to the device on the I2C bus.

    Since the fixed code works for me and presumably others, it would seem to indicate that it's a quirk of your computer/monitor
    combination.

    Can you try your code on some other hardware to convince yourself?

    Dave

    Saturday, May 25, 2019 10:07 PM
  • It can also be done with VCP codes, but it will probably fail in your case... =>

    (with right handle)

    MC_VCP_CODE_TYPE pvct;
    DWORD dwMaximumValue = 0;
    DWORD wsVersion = 0;
    // 0xDF = Version
    BOOL bRet = GetVCPFeatureAndVCPFeatureReply(handle, 0xDF, &pvct, (LPDWORD)&wsVersion, &dwMaximumValue);
    if (!bRet)
    {
    	DWORD nError = GetLastError();
    	LPVOID lpMsgBuf = NULL;
    	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
    		NULL, nError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
    	if (lpMsgBuf != NULL)
    	{
    		WCHAR wsMessage[260] = L"";
    		swprintf(wsMessage, L"%s", lpMsgBuf);
    		MessageBox(NULL, wsMessage, L"Error", MB_OK | MB_ICONERROR);
    		LocalFree(lpMsgBuf);
    	}
    }
    else
    {
    	WCHAR wsMessage[260] = L"";
    	swprintf(wsMessage, L"VCP Version : %d", wsVersion);
    	MessageBox(NULL, wsMessage, L"Information", MB_OK | MB_ICONINFORMATION);
    }
    
    // 0x10 = Brightness
    DWORD dwCurrentValue = 0;
    bRet = GetVCPFeatureAndVCPFeatureReply(handle, 0x10, &pvct, (LPDWORD)&dwCurrentValue, &dwMaximumValue);
    if (!bRet)
    {
    	DWORD nError = GetLastError();
    	LPVOID lpMsgBuf = NULL;
    	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
    		NULL, nError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
    	if (lpMsgBuf != NULL)
    	{
    		WCHAR wsMessage[260] = L"";
    		swprintf(wsMessage, L"%s", lpMsgBuf);
    		MessageBox(NULL, wsMessage, L"Error", MB_OK | MB_ICONERROR);
    		LocalFree(lpMsgBuf);
    	}
    }
    else
    {
    	WCHAR wsMessage[260] = L"";
    	swprintf(wsMessage, L"Brightness : %d", dwCurrentValue);
    	MessageBox(NULL, wsMessage, L"Information", MB_OK | MB_ICONINFORMATION);
    }


    I tried your code but as i noticed it needs 
    #include <lowlevelmonitorconfigurationapi.h>
    but including it in Qt (c++ framework which i am using to create this brightness control app) i get error no such file or folder exists while as the same is not true with 
    #include <highlevelmonitorconfigurationapi.h>
    I added an extra information to my question check it out.
    • Edited by _Ahtisham Sunday, May 26, 2019 4:58 AM edit
    Sunday, May 26, 2019 4:32 AM
  • I did this:

    if(GetMonitorBrightness(handle, &min, &cur, &max))
        {
            qDebug() << "working..!";
        }
    else
        {
            DWORD err = GetLastError();
            qDebug() << "error occurred: " << err;
        }

    And this is what I got as output:

    error occurred:  3223725442


    Since 3223725442 is not a valid system error code (see System Error Codes) I can only speculate that something is wrong with code that we have not seen or something is wrong with your system.

    I don't think anything is wrong with the code because it copy pasted it from documentation.
    I added an extra information to my question check it out.
    • Edited by _Ahtisham Sunday, May 26, 2019 4:59 AM edit
    Sunday, May 26, 2019 4:34 AM
  • Since 3223725442 is not a valid system error code (see System Error Codes) I can only speculate that something is wrong with code that we have not seen or something is wrong with your system.

    It is apparently the code he talked about : Error 0xC0262582

    "an error occurred while transmitting data to the device on the I2C bus"

    what is the solution to this problem then ? I really wanna make this app work.

    I added an extra information to my question check it out.

    • Edited by _Ahtisham Sunday, May 26, 2019 4:59 AM edit
    Sunday, May 26, 2019 4:36 AM
  • GetMonitorBrightness and SetMonitorBrigthness are not always supported for any monitor.

    Can you control brightness of your monitor from Windows Action center?

    Try this program - will it work with your monitor?

    https://clickmonitorddc.bplaced.net/

     Documentation on SetMonitorBrigthness says: "If this function is supported, the GetMonitorCapabilities function returns the MC_CAPS_BRIGHTNESS flag."

    -- pa


    Yes I can control the brightness with windows action center. 

    And I tried that program and it does work ( I wonder how did the developer of that software made it work )

    Also we have already tried GetMonitorCapabilities which didn't work it is mentioned in the previous comments of this post.

    I added an extra information to my question check it out.
    • Edited by _Ahtisham Sunday, May 26, 2019 5:00 AM edit
    Sunday, May 26, 2019 4:46 AM
  • >error occurred:  3223725442

    Which is: An error occurred while transmitting data to the device on the I2C bus.

    Since the fixed code works for me and presumably others, it would seem to indicate that it's a quirk of your computer/monitor
    combination.

    Can you try your code on some other hardware to convince yourself?

    Dave

    can you share the fixed code please ?

    I added an extra information to my question check it out.
    • Edited by _Ahtisham Sunday, May 26, 2019 5:00 AM edit
    Sunday, May 26, 2019 4:48 AM

  • And I tried that program and it does work ( I wonder how did the developer of that software made it work )

    The program uses :

    WMI (WmiMonitorBrightness)

    GetMonitorBrightness

    GetVCPFeatureAndVCPFeatureReply

    So at least one of the methods should work for you if the program works

    For GetVCPFeatureAndVCPFeatureReply, highlevelmonitorconfigurationapi.h

    is in the Windows 10 SDK


    Sunday, May 26, 2019 7:17 AM
  • >can you share the fixed code please ?

    It's nothing other than what's already been pointed out as being wrong with your initial example. Here's what I've used:

    #include <Windows.h>
    #include <physicalmonitorenumerationapi.h>
    #include <highlevelmonitorconfigurationapi.h>
    #pragma comment( lib, "Dxva2.lib" )

    int main()
    {
        HWND win_handle = GetDesktopWindow();
        HMONITOR hMon = MonitorFromWindow( win_handle, MONITOR_DEFAULTTOPRIMARY );

        if ( hMon != NULL )
        {
            DWORD num_of_monitors;
            BOOL bOK = GetNumberOfPhysicalMonitorsFromHMONITOR( hMon, &num_of_monitors );
            if ( bOK )
            {
                LPPHYSICAL_MONITOR pPhysical_monitors = ( LPPHYSICAL_MONITOR) malloc( num_of_monitors * sizeof(
    PHYSICAL_MONITOR ) );
                if ( pPhysical_monitors != NULL )
                {
                    bOK = GetPhysicalMonitorsFromHMONITOR( hMon, num_of_monitors, pPhysical_monitors );
                }

                HANDLE hMonitor = pPhysical_monitors[0].hPhysicalMonitor;

                DWORD min, cur, max;
                bOK = GetMonitorBrightness( hMonitor, &min, &cur, &max );
                if ( !bOK )
                {
                    DWORD Err = GetLastError();
                    Err = Err;
                }
                else
                {
                    // Check altering the brightness
                    bOK = SetMonitorBrightness( hMonitor, cur / 32 );

                    if ( bOK )
                    {
                        bOK = SetMonitorBrightness( hMonitor, cur );
                    }
                }
            }
        }
    }

    Sunday, May 26, 2019 9:39 AM
  • I think it would be helpful but i don't know how to write a code for this can you please help ? how would you use the class ? I checked the docs but that didn't helped.
    Sunday, May 26, 2019 1:26 PM
  • Hello _Ahtisham,

    @David Lowndes has already posted the complete code, you can simple copy and pasted, for example, in a Windows Console Application. I test it on Windows 10 1903, it does can control the display brightness.

    For using above sample code in a Qt application, you can create a Qt Console Application like this:

    All code in the main.cpp like this:

    #include <QtCore/QCoreApplication>
    
    #include <Windows.h>
    #include <physicalmonitorenumerationapi.h>
    #include <highlevelmonitorconfigurationapi.h>
    #pragma comment( lib, "Dxva2.lib" )
    
    void ControlSystemBrightess()
    {
    	HWND win_handle = GetDesktopWindow();
    	HMONITOR hMon = MonitorFromWindow(win_handle, MONITOR_DEFAULTTOPRIMARY);
    
    	if (hMon != NULL)
    	{
    		DWORD num_of_monitors;
    		BOOL bOK = GetNumberOfPhysicalMonitorsFromHMONITOR(hMon, &num_of_monitors);
    		if (bOK)
    		{
    			LPPHYSICAL_MONITOR pPhysical_monitors = (LPPHYSICAL_MONITOR)malloc(num_of_monitors * sizeof(
    				PHYSICAL_MONITOR));
    			if (pPhysical_monitors != NULL)
    			{
    				bOK = GetPhysicalMonitorsFromHMONITOR(hMon, num_of_monitors, pPhysical_monitors);
    			}
    
    			HANDLE hMonitor = pPhysical_monitors[0].hPhysicalMonitor;
    
    			DWORD min, cur, max;
    			bOK = GetMonitorBrightness(hMonitor, &min, &cur, &max);
    			if (!bOK)
    			{
    				DWORD Err = GetLastError();
    				Err = Err;
    			}
    			else
    			{
    				// Check altering the brightness
    				bOK = SetMonitorBrightness(hMonitor, cur / 32);
    
    				if (bOK)
    				{
    					bOK = SetMonitorBrightness(hMonitor, cur);
    				}
    			}
    		}
    	}
    }
    
    int main(int argc, char *argv[])
    {
    	QCoreApplication a(argc, argv);
    
    	ControlSystemBrightess();
    
    	return a.exec();
    }

    Please let me know if it helps.

    Best regards,

    Rita


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, May 30, 2019 9:40 AM
    Moderator
  • No it doesn't work I get the error. I guess you have a separate monitor ( i.e desktop ). I am running it on laptop. Also #pragma is not including the library in mine instead I have to include it by editing the .pro file of the project.
    Saturday, June 1, 2019 3:44 PM
  • GetMonitorBrightness and SetMonitorBrigthness are not always supported for any monitor.

    Can you control brightness of your monitor from Windows Action center?

    Try this program - will it work with your monitor?

    https://clickmonitorddc.bplaced.net/

     Documentation on SetMonitorBrigthness says: "If this function is supported, the GetMonitorCapabilities function returns the MC_CAPS_BRIGHTNESS flag."

    -- pa


    Yes I can control the brightness with windows action center. 

    And I tried that program and it does work ( I wonder how did the developer of that software made it work )

    Also we have already tried GetMonitorCapabilities which didn't work it is mentioned in the previous comments of this post.

    I added an extra information to my question check it out.

    Hello _Ahtisham,

    If you mean GetMonitorCapabilities fails on your laptop, it may not support DDC/CI. You need contact the support of your laptop to confirm if it support DDC/CI and how to enable DDC/CI.

    Best regards,

    Rita


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, June 3, 2019 10:04 AM
    Moderator