MENU

C++调节显示器的亮度SetDeviceGammaRamp

October 27, 2019 • 默认分类

原理

SetDeviceGammaRamp API函数位于 Gdi32.ll 中,接收一个 256*3 RGB 值的数组。
增加这个数组中的值会使屏幕更亮,而减少这些值会使屏幕变暗。
可以通过增加或减少的红/绿/蓝成分的值来显示影响。例如:在所有RGB值中增加蓝色分量将增加整个显示的蓝色。
下面的类封装调用 GetDeviceGammaRampSetDeviceGammaRamp,并设置屏幕的亮度,提供 setbrightness 功能。

GammaRamp.h

#ifndef GAMMARAMP_H_
#define GAMMARAMP_H_

/*
CGammaRamp class

Encapsulates the Gamma Ramp API and changes the brightness of 
the entire screen.

Written by Nir Sofer.
http://www.nirsoft.net

*/

class CGammaRamp
{
protected:
    HMODULE hGDI32;
    HDC hScreenDC;
    typedef BOOL (WINAPI *Type_GetDeviceGammaRamp)(HDC hDC, LPVOID lpRamp);
    typedef BOOL (WINAPI *Type_SetDeviceGammaRamp)(HDC hDC, LPVOID lpRamp);

    Type_GetDeviceGammaRamp pGetDeviceGammaRamp;
    Type_SetDeviceGammaRamp pSetDeviceGammaRamp;

public:

    CGammaRamp();
    ~CGammaRamp();
    BOOL LoadLibrary();
    void FreeLibrary();
    BOOL LoadLibraryIfNeeded();
    BOOL SetDeviceGammaRamp(HDC hDC, LPVOID lpRamp);
    BOOL GetDeviceGammaRamp(HDC hDC, LPVOID lpRamp);
    BOOL SetBrightness(HDC hDC, WORD wBrightness);

};
#endif//#ifndef GAMMARAMP_H_

GammaRamp.cpp

#include <windows.h>
#include "gammaramp.h"

/*
CGammaRamp class

Encapsulates the Gamma Ramp API and changes the brightness of 
the entire screen.

Written by Nir Sofer.
http://www.nirsoft.net
*/

CGammaRamp::CGammaRamp()
{
    //Initialize all variables.
    hGDI32 = NULL;
    hScreenDC = NULL;
    pGetDeviceGammaRamp = NULL;
    pSetDeviceGammaRamp = NULL;
}

CGammaRamp::~CGammaRamp()
{
    FreeLibrary();
}

BOOL CGammaRamp::LoadLibrary()
{
    BOOL bReturn = FALSE;

    FreeLibrary();
    //Load the GDI library.
    hGDI32 = ::LoadLibrary("gdi32.dll");
    if (hGDI32 != NULL)
    {
        //Get the addresses of GetDeviceGammaRamp and SetDeviceGammaRamp API functions.
        pGetDeviceGammaRamp = (Type_GetDeviceGammaRamp)GetProcAddress(hGDI32, "GetDeviceGammaRamp");
        pSetDeviceGammaRamp = (Type_SetDeviceGammaRamp)GetProcAddress(hGDI32, "SetDeviceGammaRamp");
        
        //Return TRUE only if these functions exist.
        if (pGetDeviceGammaRamp == NULL || pSetDeviceGammaRamp == NULL)
        {
            FreeLibrary();
        }
        else
        {
            bReturn = TRUE;
        }
    }
    return bReturn;
}


void CGammaRamp::FreeLibrary()
{
    //Free the GDI library.
    if (hGDI32 != NULL) 
    {
        ::FreeLibrary(hGDI32);
        hGDI32 = NULL;
    }
}

BOOL CGammaRamp::LoadLibraryIfNeeded()
{
    BOOL bReturn = FALSE;
    if (hGDI32 == NULL)
    {
        LoadLibrary();
    }
    if (pGetDeviceGammaRamp != NULL && pSetDeviceGammaRamp != NULL)
    {
        bReturn = TRUE;
    }
    return bReturn;
}

BOOL CGammaRamp::SetDeviceGammaRamp(HDC hDC, LPVOID lpRamp)
{
    //Call to SetDeviceGammaRamp only if this function is successfully loaded.
    if (LoadLibraryIfNeeded())
    {
        return pSetDeviceGammaRamp(hDC, lpRamp);
    }
    else
    {
        return FALSE;
    }
}

BOOL CGammaRamp::GetDeviceGammaRamp(HDC hDC, LPVOID lpRamp)
{
    //Call to GetDeviceGammaRamp only if this function is successfully loaded.
    if (LoadLibraryIfNeeded())
    {
        return pGetDeviceGammaRamp(hDC, lpRamp);
    }
    else
    {
        return FALSE;
    }

}

BOOL CGammaRamp::SetBrightness(HDC hDC, WORD wBrightness)
{
    /*
    Changes the brightness of the entire screen.
    This function may not work properly in some video cards.

    The wBrightness value should be a number between 0 and 255.
    128 = Regular brightness
    above 128 = brighter
    below 128 = darker

    If hDC is NULL, SetBrightness automatically load and release 
    the display device context for you.

    */
    BOOL bReturn = FALSE;
    HDC hGammaDC = hDC;

    //Load the display device context of the entire screen if hDC is NULL.
    if (hDC == NULL)
        hGammaDC = GetDC(NULL);

    if (hGammaDC != NULL)
    {
        //Generate the 256-colors array for the specified wBrightness value.
        WORD GammaArray[3][256];

        for (int iIndex = 0; iIndex < 256; iIndex++)
        {
            int iArrayValue = iIndex * (wBrightness + 128);

            if (iArrayValue > 65535)
            {
                iArrayValue = 65535;
            }
            GammaArray[0][iIndex] = 
            GammaArray[1][iIndex] = 
            GammaArray[2][iIndex] = (WORD)iArrayValue;
        }

        //Set the GammaArray values into the display device context.
        bReturn = SetDeviceGammaRamp(hGammaDC, GammaArray);
    }
    if (hDC == NULL)
    {
        ReleaseDC(NULL, hGammaDC);
    }
    return bReturn;
}

用法

#include <Windows.h>
#include "gammaramp.h"

int WINAPI WinMain(
  HINSTANCE hInstance,        // handle to current instance
  HINSTANCE hPrevInstance,    // handle to previous instance
  LPSTR lpCmdLine,                 // command line
  int nCmdShow                      // show state
)
{
    //Example for changing the brightness with CGammaRamp class:
    //Be aware that this exmaple may not work properly in all Video cards.

    CGammaRamp GammaRamp;

    //Make the screen darker:
    GammaRamp.SetBrightness(NULL, 64);

    //Wait 3 seconds:
    Sleep(3000);

    //Return back to normal:
    GammaRamp.SetBrightness(NULL, 128);

    return 0;
}

资料

Changing the screen brightness programmingly - By using the Gamma Ramp API

Leave a Comment

已有 1 条评论
  1. 游客 游客

    OωO 这个是调整伽马值,不同显示器有不同的伽马校对,不能乱调。