How to change gamma and brightness values for multi monitor setups

sValentin 81 Reputation points
2023-10-10T09:08:39.2+00:00

I'm trying to add a functionality to my app with which you can change gamma and brightness of any monitor connected.

For gamma I was looking at GetDeviceGammaRamp / SetDeviceGammaRamp, but on that page it says: "We strongly recommend that you don't use this API.". So, in this case, what else should I use to be able to change gamma for multi monitor setups?

As for brightness I was looking at GetMonitorBrightness / SetMonitorBrightness, but these also have a warning. Is there something else to use for this? Like with gamma I need something that supports multi monitor setups, and not changing the values for all monitors the same.

I'm only interested in Windows support, and no other OS.

Windows development | Windows API - Win32
Windows for business | Windows Client for IT Pros | User experience | Other
Developer technologies | C++
{count} votes

3 answers

Sort by: Most helpful
  1. Castorix31 90,686 Reputation points
    2023-10-10T09:20:59.4466667+00:00

    With SetVCPFeature

    (for example, Gamma : VCP code = 0x72)


  2. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  3. sValentin 81 Reputation points
    2023-10-20T19:25:32.0633333+00:00

    I already posted an answer, but again it seems that it didn't got actually posted here, just like the comments. It says it is posted, but it doesn't appear. I already found a solution for when you have multiple monitors. I'll post parts of the code again as I don't have the full code I posted before with all the explanations:

    General function:

    static int hasAttachedScreen(int monitorIndex) {
    	DISPLAY_DEVICE display{};
    	display.cb = sizeof(DISPLAY_DEVICE);
    	int ok = EnumDisplayDevicesW(NULL, monitorIndex, &display, 0);
    	return ok != 0 && display.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
    }
    

    To set gamma:

    BOOL setGamma(int monitorIndex, double gamma[]) {
    	HDC hdc = GetDC(0);
    	if (hasAttachedScreen(monitorIndex)) {
    		DISPLAY_DEVICE display{};
    		display.cb = sizeof(DISPLAY_DEVICE);
    		EnumDisplayDevicesW(NULL, monitorIndex, &display, 0);
    		hdc = CreateDC(NULL, display.DeviceName, NULL, 0);
    	}
    	else {
    		hdc = NULL;
    	}
    
    	if (hdc != NULL) {
    		WORD ramp[256 * 3]{};
    		for (int i = 0; i < 256; i++) {
    			ramp[i] = (WORD)gamma[i];
    			ramp[i + 256] = (WORD)gamma[i];
    			ramp[i + 512] = (WORD)gamma[i];
    		}
    		BOOL result = SetDeviceGammaRamp(hdc, ramp);
    		ReleaseDC(0, hdc);
    		return result;
    	}
    	else {
    		return false;
    	}
    }
    

    To get gamma:

    void getGamma(int monitorIndex) {
    	HDC hdc = GetDC(0);
    	if (hasAttachedScreen(monitorIndex)) {
    		DISPLAY_DEVICE display{};
    		display.cb = sizeof(DISPLAY_DEVICE);
    		EnumDisplayDevicesW(NULL, monitorIndex, &display, 0);
    		hdc = CreateDC(NULL, display.DeviceName, NULL, 0);
    	}
    	else {
    		hdc = NULL;
    	}
    
    	if (hdc != NULL) {
    		WORD ramp[256 * 3]{};
    		BOOL result = GetDeviceGammaRamp(hdc, ramp);
    		ReleaseDC(0, hdc);
    		if (result) {
    			// Code...
    		}
    		else {
    			// Code...
    		}
    	}
    	else {
    		// Code...
    	}
    }
    

    //Edit: I don't know why but my messages aren't getting posted right. Maybe it is the website, or a problem with my account, I don't know. When I posted this answer the code I added for set gamma only contained function header...

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.