I want to implement a program for adjusting the brightness of all monitors using Qt. I am a beginner and have been searching for a long time for information. Can anyone give me some ideas? Thanks!
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;
}
This is what I tried before, Adjusting gamma values using SetDeviceGammaRamp works correctly in single monitor or multiple monitors in clone mode. However, it does not have any effect when there are multiple monitors, even though I obtain the corresponding HDCs for each monitor.
I also found another way, but unfortunately, it only works on the external screen and not on my laptop screen.
#include "Ioctl.h"
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <iostream>
#include <Ntddvdeo.h>
#include "QDebug"
#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 Ioctl::setBrightness(int level)
{
HANDLE h;
DWORD nOutBufferSize = 256;
BYTE SupportedBrightness[256];
DWORD g_supportedLevelCount;
DISPLAY_BRIGHTNESS DisplayBrightness;
memset(SupportedBrightness, 0, sizeof(SupportedBrightness));
/* use createfile function to open lcd.
* url from microsoft about IOCTL code.
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa372703%28v=vs.85%29.aspx
*/
/*
* char* 和 wchar_t* 互相转换参考博客
* https://www.cnblogs.com/icqw/p/4614877.html
*/
/*
* c++代码参考博客
* https://blog.csdn.net/weixin_34111819/article/details/86328019
*/
char temchar[] = "\\\\.\\LCD";
char* szSour = temchar;
WCHAR Temp[128] = { 0 };
mbstowcs(Temp, szSour, strlen(szSour));
h = CreateFileW(Temp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
if (h == INVALID_HANDLE_VALUE) {
qDebug()<<"Open \\\\.\\LCD error";
exit(1);
}
/* Query for display supported level */
if (!DeviceIoControl(h, IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS, NULL, 0, SupportedBrightness, nOutBufferSize, &g_supportedLevelCount, NULL)) {
qDebug()<<"IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize;
exit(1);
}
if (g_supportedLevelCount == 0) /* 0 means not supported */
{
qDebug()<<"\nLCD not support LEVEL COUNT", g_supportedLevelCount;
exit(1);
}
DisplayBrightness.ucDisplayPolicy = 0;
DisplayBrightness.ucACBrightness = level;
DisplayBrightness.ucDCBrightness = level;
/* Set display backlight level */
nOutBufferSize = sizeof(DisplayBrightness);
if (!DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS, (DISPLAY_BRIGHTNESS*)&DisplayBrightness, nOutBufferSize, NULL, 0, &nOutBufferSize, NULL)) {
qDebug()<<"IOCTL_VIDEO_SET_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize;
exit(1);
}
Sleep(500); /* delay for some time while wmi event changed */
nOutBufferSize = sizeof(DisplayBrightness);
if (!DeviceIoControl(h, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS, NULL, 0, (DISPLAY_BRIGHTNESS*)&DisplayBrightness, nOutBufferSize, &nOutBufferSize, NULL)) {
qDebug()<<"IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize;
exit(1);
}
qDebug()<<"\nBrightness_AC: %d\nBrightness_DC: %d", DisplayBrightness.ucACBrightness, DisplayBrightness.ucDCBrightness;
}
This is not possible to do using Qt. You'll have to use native Windows APIs.
Here are the various examples on how to do things for Windows using Win32 API: https://github.com/alervd/monitor
There you'll find code examples on how to enumerate displays and how to control them.