2016-09-01 164 views
1

我試圖在Windows 10機器上設置亮度。顯示器似乎不支持setMonitorBrightness,而setDeviceGammaRamp會改變gamma,白點等,所以我會盡量不使用它。使用C++在Windows 10上設置亮度WinAPI

我試圖讓這個工作使用IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS控制。當我拿着顯示器手柄使用CreateFile()時,我檢查手柄是否無效並且沒有問題。但是當我撥打DeviceIoControl()IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS時,我得到ERROR_INVALID_HANDLE(錯誤6)。

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; 
} 

而且,我應該使用CreateFile()獲得監視器句柄,或者我可以叫MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY)呢?

+3

'&olp'是一個指向未初始化的'OVERLAPPED'結構,具有手柄的事件對象。我假設這是* DeviceIoControl'抱怨的*無效句柄。無論如何,您不需要傳遞'OVERLAPPED'結構,只需傳遞'NULL'即可。 – IInspectable

+0

這完全是問題。非常感謝! – user1065969

回答

0

在呼叫

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

&olp點到一個未初始化的OVERLAPPED結構。該結構具有事件對象的句柄(hEvent),該句柄包含一個隨機值。這是DeviceIoControl電話抱怨的無效處理。

既然你不是用FILE_FLAG_OVERLAPPED標誌(這真的不會使一個顯示裝置感反正)你並不需要在所有傳遞一個OVERLAPPED結構調用CreateFile。簡單地傳遞NULL,呼叫會成功:

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