4

I am trying to set the brightness on a Windows 10 machine. The display doesn't seem to support setMonitorBrightness, and setDeviceGammaRamp alters the gamma, white point etc, so I would try not to use it.

I am trying to get this to work using IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS control. When I get the monitor handle using CreateFile(), I check if the handle is invalid and it is fine. But I get ERROR_INVALID_HANDLE (error 6) when I call DeviceIoControl() with IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS.

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

DISPLAY_BRIGHTNESS _displayBrightness;

_displayBrightness.ucDisplayPolicy = 0;
_displayBrightness.ucACBrightness = 0;  //for testing purposes
_displayBrightness.ucDCBrightness = 0;

DWORD ret = NULL;
OVERLAPPED olp;

DWORD nOutBufferSize = sizeof(_displayBrightness);
HANDLE h = CreateFile(L"\\\\.\\LCD",
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    OPEN_EXISTING,
    0, NULL);

if (h == INVALID_HANDLE_VALUE) {
    //Does not reach here
    return false;
}  

if (!DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS, (DISPLAY_BRIGHTNESS *)&_displayBrightness, nOutBufferSize, NULL, 0, &ret, &olp))
{
    // GetLastError() returns error code 6 - Invalid handle 
    return false;
} 

Also, should I be using CreateFile() to get the monitor handle, or can I call MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY) instead?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
user1065969
  • 589
  • 4
  • 10
  • 19
  • 4
    `&olp` is a pointer to an uninitialized `OVERLAPPED` structure, that has a handle to an event object. I'd assume that that is the *invalid handle* the `DeviceIoControl` complains about. You don't need to pass an `OVERLAPPED` structure anyway, so simply pass `NULL`. – IInspectable Sep 01 '16 at 09:33
  • That was EXACTLY the issue. Thank you so much! – user1065969 Sep 01 '16 at 12:55

1 Answers1

3

In the call

DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS,
                (DISPLAY_BRIGHTNESS*)&_displayBrightness, nOutBufferSize, NULL, 0, &ret,
                &olp)

&olp points to an uninitialized OVERLAPPED structure. This structure has a handle to an event object (hEvent), that holds a random value. This is the invalid handle the DeviceIoControl call complains about.

Since you aren't calling CreateFile with a FILE_FLAG_OVERLAPPED flag (which really wouldn't make sense for a display device anyway) you don't need to pass an OVERLAPPED structure at all. Simply pass NULL, and the call will succeed:

DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS,
                (DISPLAY_BRIGHTNESS*)&_displayBrightness, nOutBufferSize, NULL, 0, &ret,
                NULL)
IInspectable
  • 46,945
  • 8
  • 85
  • 181