I'm working on C++ display brightness regulation program for windows 10. The setup is: notebook with internal display + external HDMI display.
#include <Windows.h>
#include <iostream>
#include <vector>
#include <highlevelmonitorconfigurationapi.h>
#pragma comment(lib, "Dxva2.lib")
void ListMonitorsAndAdapters()
{
DISPLAY_DEVICE displayDevice;
displayDevice.cb = sizeof(DISPLAY_DEVICE);
for (DWORD deviceIndex = 0; EnumDisplayDevices(nullptr, deviceIndex, &displayDevice, 0); deviceIndex++)
{
std::wcout << "Monitor: " << displayDevice.DeviceName << " Video Adapter: " << displayDevice.DeviceString << std::endl;
}
}
void SetMonitorBrightness_f(HANDLE hMonitor, DWORD newBrightness)
{
DWORD minBrightness, maxBrightness, currentBrightness;
if (GetMonitorBrightness(hMonitor, &minBrightness, ¤tBrightness, &maxBrightness))
{
DWORD newNormalizedBrightness = (newBrightness * (maxBrightness - minBrightness)) / 100 + minBrightness;
SetMonitorBrightness(hMonitor, newNormalizedBrightness);
}
}
std::vector<HANDLE> GetPhysicalMonitors()
{
std::vector<HANDLE> physicalMonitors;
std::vector<HMONITOR> monitors;
EnumDisplayMonitors(NULL, NULL, [](HMONITOR monitor, HDC, LPRECT, LPARAM lParam) -> BOOL {
std::vector<HMONITOR>* monitors = reinterpret_cast<std::vector<HMONITOR>*>(lParam);
monitors->push_back(monitor);
return TRUE;
}, reinterpret_cast<LPARAM>(&monitors));
for (HMONITOR monitor : monitors)
{
DWORD numPhysicalMonitors;
if (GetNumberOfPhysicalMonitorsFromHMONITOR(monitor, &numPhysicalMonitors))
{
if (numPhysicalMonitors == 1)
{
// Laptop monitor
PHYSICAL_MONITOR physicalMonitor;
if (GetPhysicalMonitorsFromHMONITOR(monitor, 1, &physicalMonitor))
{
physicalMonitors.push_back(physicalMonitor.hPhysicalMonitor);
}
}
else
{
// Secondary monitor (HDMI monitor, etc.)
PHYSICAL_MONITOR* physicalMonitorArray = new PHYSICAL_MONITOR[numPhysicalMonitors];
if (GetPhysicalMonitorsFromHMONITOR(monitor, numPhysicalMonitors, physicalMonitorArray))
{
for (DWORD i = 0; i < numPhysicalMonitors; ++i)
{
physicalMonitors.push_back(physicalMonitorArray[i].hPhysicalMonitor);
}
}
delete[] physicalMonitorArray;
}
}
}
return physicalMonitors;
}
int main()
{
ListMonitorsAndAdapters();
std::vector<HANDLE> physicalMonitors = GetPhysicalMonitors();
if (physicalMonitors.empty())
{
std::cerr << "Both laptop monitor and HDMI monitor are not detected." << std::endl;
return 1;
}
// Adjust brightness of the laptop monitor (primary monitor)
DWORD laptopBrightness = 20; // Adjust the value as desired (0-100)
SetMonitorBrightness_f(physicalMonitors[0], laptopBrightness);
// Adjust brightness of the HDMI monitor (secondary monitor)
if (physicalMonitors.size() > 1)
{
DWORD hdmiBrightness = 50; // Adjust the value as desired (0-100)
SetMonitorBrightness_f(physicalMonitors[1], hdmiBrightness);
}
}
The problem is that brightness is changing only for HDMI display but not for internal notebook display.
ListMonitorsAndAdapters() function cout:
Monitor: \\.\DISPLAY1 Video Adapter: AMD Radeon(TM) Graphics
Monitor: \\.\DISPLAY2 Video Adapter: AMD Radeon(TM) Graphics
Monitor: \\.\DISPLAY3 Video Adapter: NVIDIA GeForce RTX 3060 Laptop GPU
Monitor: \\.\DISPLAY4 Video Adapter: NVIDIA GeForce RTX 3060 Laptop GPU
Monitor: \\.\DISPLAY5 Video Adapter: NVIDIA GeForce RTX 3060 Laptop GPU
Monitor: \\.\DISPLAY6 Video Adapter: NVIDIA GeForce RTX 3060 Laptop GPU
I tried different methods to open internal notebook display like
HANDLE hMonitor = CreateFile(L"\\\\.\\LCD", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
but still no luck.
I found the solution to change laptop display brightness by using WMI from this topic. It's a bit dirty method but it works (should be something like this, but I never had to make it work). So the final code for changing both HDMI and notebook displays brightness:
UPD. Finlay got it works with WMI Class. So now you have 2 functions to control notebook display brightness (WMI or PowerShell) and 1 for HDMI display: