• Welcome to Theos PowerBasic Museum 2017.

SetDeviceGammaRamp

Started by John Thompson, September 07, 2009, 06:10:28 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

John Thompson

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!

José Roca

 
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))


John Thompson


#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!

Edwin Knoppert

Shouldn't this:
FUNCTION = SetDeviceGammaRamp(hDesktopDC, GammaArray(0))

be:

FUNCTION = SetDeviceGammaRamp(hDesktopDC, ByVal Varptr( GammaArray(0) ))

?

José Roca

 
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.

José Roca

 
Hi John,

C int variables are LONGs, not INTEGERs. If declared as INTEGER, instead of LONG, iArrayValue will become negative when greater than 32767.

John Thompson

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!

Patrice Terrier

#7
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


...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

José Roca

 
Thanks. The C notation for arrays always confuses me.

Patrice Terrier

Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

John Thompson

Thanks!  (It worked perfect on a Asus EEE PC 1000HD Windows 7).