miércoles, 7 de julio de 2010

Controla el nivel de backlight de una lcd

Hoy en día la mayoría de los portatiles, por no decir todos permiten cambiar el nivel backlight o de luz que emite la pantalla.

Aunque me a costado he conseguido encontrar la información suficiente para poder hacer un primer ejemplo funcional, por lo menos en mi Asus EeePC, aunque estoy seguro que funciona en la mayoría.

Las primeras 25 líneas no harían falta si tienes el kit de desarrollo de drivers de Windows.

#include <windows.h>
#include <iostream>

using namespace std;

typedef struct _DISPLAY_BRIGHTNESS
{
    UCHAR ucDisplayPolicy;
    UCHAR ucACBrightness;
    UCHAR ucDCBrightness;
} DISPLAY_BRIGHTNESS, *PDISPLAY_BRIGHTNESS;

#define FILE_DEVICE_VIDEO   0x00000023
#define METHOD_BUFFERED     0
#define FILE_ANY_ACCESS     0

#define CTL_CODE(a,b,c,d) ((a)<<16 | (b)<<2 | (c)<<14 | (d))

#define IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS \
    CTL_CODE(FILE_DEVICE_VIDEO, 0x125, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS \
    CTL_CODE(FILE_DEVICE_VIDEO, 0x126, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS \
    CTL_CODE(FILE_DEVICE_VIDEO, 0x127, METHOD_BUFFERED, FILE_ANY_ACCESS)

int main(void)
{
    HANDLE hLCD = CreateFile("\\\\.\\LCD",       // open LCD device
                             GENERIC_READ,                  // access to the drive
                             FILE_SHARE_READ|FILE_SHARE_WRITE,// share mode
                             NULL,                          // default security attributes
                             OPEN_EXISTING,                 // disposition
                             0,                             // file attributes
                             NULL);

    if (hLCD == INVALID_HANDLE_VALUE)
    {
        cout << "error:" << GetLastError() << endl;
        return 1;
    }

    BYTE SupportedBrightness[256];
    DWORD nBytesReturned;

    int nRes = DeviceIoControl(
                   (HANDLE) hLCD,                           // handle to device
                   IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS,  // dwIoControlCode
                   NULL,                                    // lpInBuffer
                   0,                                       // nInBufferSize
                   (LPVOID) SupportedBrightness,            // output buffer
                   sizeof(SupportedBrightness),             // size of output buffer
                   (LPDWORD) &nBytesReturned,               // bytes returned
                   NULL                                     // OVERLAPPED
               );

    if (nRes == 0)
    {
        cout << "error:" << GetLastError() << endl;
        return 2;
    }

    cout << "Niveles soportados: ";
    for (DWORD i=0; i<nBytesReturned; i++)
    {
        cout << (DWORD)SupportedBrightness[i] << ", ";
    }
    cout << endl << endl;

    DISPLAY_BRIGHTNESS DisplayBrightness;
    nRes = DeviceIoControl(
               (HANDLE) hLCD,                           // handle to device
               IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS,    // dwIoControlCode
               NULL,                                    // lpInBuffer
               0,                                       // nInBufferSize
               (LPVOID) &DisplayBrightness,             // output buffer
               sizeof(DisplayBrightness),               // size of output buffer
               (LPDWORD) &nBytesReturned,               // bytes returned
               NULL                                     // OVERLAPPED
           );

    if (nRes == 0)
    {
        cout << "error:" << GetLastError() << endl;
        return 3;
    }

    cout << "DisplayPolicy: " << (int)DisplayBrightness.ucDisplayPolicy << endl
         << "ACBrightness: " << (int)DisplayBrightness.ucACBrightness  << endl
         << "DCBrightness: " << (int)DisplayBrightness.ucDCBrightness << endl
         << endl;

    system("PAUSE");

    DISPLAY_BRIGHTNESS ON = {2,36,36};  // eeePC max
    DISPLAY_BRIGHTNESS OFF = {2,1,1};
    while (!GetAsyncKeyState(VK_ESCAPE))
    {
        Sleep(500);
        DeviceIoControl((HANDLE) hLCD,IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS,(LPVOID)&ON,sizeof(DISPLAY_BRIGHTNESS),NULL,0,(LPDWORD) &nBytesReturned,NULL);
        Sleep(500);
        DeviceIoControl((HANDLE) hLCD,IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS,(LPVOID)&OFF,sizeof(DISPLAY_BRIGHTNESS),NULL,0,(LPDWORD) &nBytesReturned,NULL);
    }

    nRes = DeviceIoControl(
               (HANDLE) hLCD,                           // handle to device
               IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS,      // dwIoControlCode
               (LPVOID) &DisplayBrightness,             // lpInBuffer
               sizeof(DisplayBrightness),               // nInBufferSize
               NULL,                                    // output buffer
               0,                                       // size of output buffer
               (LPDWORD) &nBytesReturned,               // bytes returned
               NULL                                     // OVERLAPPED
           );

    if (nRes == 0)
    {
        cout << "error:" << GetLastError() << endl;
        return 4;
    }

    CloseHandle(hLCD);
    return 0;
}

Comparte o puntua esta publicación ▼

2 comentarios:

Anónimo dijo...

Hello, thank you for the example. Do you know why this may not work under windows 8.1? I'm assuming it maybe a driver issue, which I'm looking into, but thought you may have heard of or experienced this yourself? I know this is quite an old post but doesn't hurt to try.
PS. I used google translate to translate this to Spanish from English so apologies if it (the Spanish) doesn't make any sense.

..................................................................
Hola , gracias por el ejemplo . ¿Sabe usted por qué esto puede no funcionar en Windows 8.1? Estoy asumiendo que tal vez un problema de controladores , lo que estoy buscando en , pero pensamos que puede haber escuchado o experimentado esto mismo? Sé que esto es bastante una entrada antigua , pero no se pierde nada con intentarlo .

PD. He utilizado Google Translate para traducir esto al español del Inglés así que disculpas si ( el español ) no

David Gonzalez dijo...

yes, drivers.
Some Asus EeePC does not have drivers for Windows 8+.
=(

Publicar un comentario