I'm trying to use SetDeviceGammaRamp to change the brightness on my computer display. I have compilable C++ source code ( http://nirsoft.net/vc/change_brightness.zip ) that compiles and works, but I am having a problem creating the array that is expected.
MSDN states
Quote
Syntax
BOOL WINAPI SetDeviceGammaRamp(
HDC hDC,
LPVOID lpRamp
);
Parameters
hDC
Specifies the device context of the direct color display board in question.
lpRamp
Pointer to a buffer containing the gamma ramp to be set. The gamma ramp is specified in three arrays of 256 WORD elements each, which contain the mapping between RGB values in the frame buffer and digital-analog-converter (DAC ) values. The sequence of the arrays is red, green, blue. The RGB values must be stored in the most significant bits of each WORD to increase DAC independence.
Return Value
If this function succeeds, the return value is TRUE.
If this function fails, the return value is FALSE.
This is what the C++ source code does:
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;
}
My problem is with the GammaArray (). Can anyone explain how that could be converted to PB with WinAPI 114?
Thanks!
It must be something like this:
DIM GammaArray(255, 255, 255) AS WORD
FOR iIndex = 0 TO 255
iArrayValue = iIndex * (wBrightness + 128)
IF iArrayValue > 65535 THEN iArrayValue = 65535
GammaArray(0, iIndex) = iArrayValue
GammaArray(1, iIndex) = iArrayValue
GammaArray(2, iIndex) = iArrayValue
NEXT
bReturn = SetDeviceGammaRamp(hGammaDC, GammaArray(0))
#COMPILE EXE
#DIM ALL
#INCLUDE "Win32API.INC"
FUNCTION SetScreenBrightness ( wBrightness AS LONG ) AS LONG
LOCAL hDesktopDC AS DWORD
LOCAL iIndex AS INTEGER
LOCAL iArrayValue AS INTEGER
DIM GammaArray(255, 255, 255) AS WORD
hDesktopDC = GetDc ( %NULL )
FOR iIndex = 0 TO 255
iArrayValue = iIndex * (wBrightness + 128)
IF iArrayValue > 65535 THEN iArrayValue = 65535
GammaArray(0, iIndex) = iArrayValue
GammaArray(1, iIndex) = iArrayValue
GammaArray(2, iIndex) = iArrayValue
NEXT
FUNCTION = SetDeviceGammaRamp(hDesktopDC, GammaArray(0))
END FUNCTION
FUNCTION PBMAIN () AS LONG
LOCAL lRC AS LONG
lRC = SetScreenBrightness ( 64 )
MSGBOX FORMAT$(lRC)
SLEEP 3000
lRC = SetScreenBrightness ( 128 )
MSGBOX FORMAT$(lRC)
END FUNCTION
My Windows XP computer crashed last night so I now tried this on my Windows 7 netbook (including with admin rights) and no luck. I'm going to try it on another Windows XP computer and I'll report back.
Thanks for your help!
Shouldn't this:
FUNCTION = SetDeviceGammaRamp(hDesktopDC, GammaArray(0))
be:
FUNCTION = SetDeviceGammaRamp(hDesktopDC, ByVal Varptr( GammaArray(0) ))
?
As the parameter is declared BYREF ANY, ByVal Varptr( GammaArray(0) will do the same that GammaArray(0): to pass a pointer by value to the first element of the array.
Hi John,
C int variables are LONGs, not INTEGERs. If declared as INTEGER, instead of LONG, iArrayValue will become negative when greater than 32767.
I wasn't able to find a Windows XP machine last night, but I should be able to test it on one today. I updated the integers to longs and tried again in Win 7 (first normally, then as administrator) in case it would work, but still get lRC = 0. I'll report back with Windows XP findings. Thanks!
Here it is in plain SDK :)
#COMPILE EXE
#OPTION VERSION5
DECLARE SUB apiSleep LIB "KERNEL32.DLL" ALIAS "Sleep" (BYVAL dwMilliseconds AS DWORD)
DECLARE FUNCTION GetDC LIB "USER32.DLL" ALIAS "GetDC" (BYVAL hWnd AS DWORD) AS DWORD
DECLARE FUNCTION ReleaseDC LIB "USER32.DLL" ALIAS "ReleaseDC" (BYVAL hWnd AS DWORD, BYVAL hDC AS DWORD) AS LONG
DECLARE FUNCTION GetDeviceGammaRamp LIB "GDI32.DLL" ALIAS "GetDeviceGammaRamp" (BYVAL hDC AS DWORD, lpRamp AS ANY) AS LONG
DECLARE FUNCTION SetDeviceGammaRamp LIB "GDI32.DLL" ALIAS "SetDeviceGammaRamp" (BYVAL hDC AS DWORD, lpRamp AS ANY) AS LONG
DECLARE FUNCTION zTrace LIB "zTrace.DLL" ALIAS "zTrace" (zMessage AS ASCIIZ) AS LONG
FUNCTION SetBrightness(BYVAL hDC AS LONG, BYVAL wBrightness AS WORD) AS LONG
' /*
' 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.
'
' */
LOCAL bReturn, hGammaDC, nIndex AS LONG
LOCAL wValue AS WORD
bReturn = 0
hGammaDC = hDC
' //Load the display device context of the entire screen if hDC is NULL.
IF hDC = 0 THEN hGammaDC = GetDC(0)
IF hGammaDC THEN
' //Generate the 256-colors array for the specified wBrightness value.
DIM GammaArray(255, 2) AS WORD
FOR nIndex = 0 TO 255
wValue = MIN&(nIndex * (wBrightness + 128), 65535)
GammaArray(nIndex, 0) = wValue
GammaArray(nIndex, 1) = wValue
GammaArray(nIndex, 2) = wValue
NEXT
' //Set the GammaArray values into the display device context.
bReturn = SetDeviceGammaRamp(hGammaDC, GammaArray(0, 0))
END IF
IF hDC = 0 THEN CALL ReleaseDC(0, hGammaDC)
FUNCTION = bReturn
END FUNCTION
FUNCTION WinMain (BYVAL hInstance AS LONG, _
BYVAL hPrevInstance AS LONG, _
BYVAL lpCmdLine AS ASCIIZ PTR, _
BYVAL iCmdShow AS LONG) AS LONG
' //Make the screen darker:
CALL SetBrightness(0, 64)
' //Wait 3 seconds:
apiSleep(3000)
' //Return back to normal:
CALL SetBrightness(0, 128)
END FUNCTION
...
Thanks. The C notation for arrays always confuses me.
Glad i could help ;)
...
Thanks! (It worked perfect on a Asus EEE PC 1000HD Windows 7).