Adjust screen brightness using C#
Look at the SetDeviceGammaRamp API function. There's a CodeProject article that describes using it from C# here: Setting Screen Brightness in C#
Be aware that your graphics card has to support this though, I'd assume that most modern ones do, but I don't know.
Edit: Since the CodeProject article seems to be down, another place to find out how to call it from C# is on the pInvoke site.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PHYSICAL_MONITOR
{
public IntPtr hPhysicalMonitor;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szPhysicalMonitorDescription;
}
public class BrightnessController : IDisposable
{
[DllImport("user32.dll", EntryPoint = "MonitorFromWindow")]
public static extern IntPtr MonitorFromWindow([In] IntPtr hwnd, uint dwFlags);
[DllImport("dxva2.dll", EntryPoint = "DestroyPhysicalMonitors")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DestroyPhysicalMonitors(uint dwPhysicalMonitorArraySize, ref PHYSICAL_MONITOR[] pPhysicalMonitorArray);
[DllImport("dxva2.dll", EntryPoint = "GetNumberOfPhysicalMonitorsFromHMONITOR")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetNumberOfPhysicalMonitorsFromHMONITOR(IntPtr hMonitor, ref uint pdwNumberOfPhysicalMonitors);
[DllImport("dxva2.dll", EntryPoint = "GetPhysicalMonitorsFromHMONITOR")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetPhysicalMonitorsFromHMONITOR(IntPtr hMonitor, uint dwPhysicalMonitorArraySize, [Out] PHYSICAL_MONITOR[] pPhysicalMonitorArray);
[DllImport("dxva2.dll", EntryPoint = "GetMonitorBrightness")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetMonitorBrightness(IntPtr handle, ref uint minimumBrightness, ref uint currentBrightness, ref uint maxBrightness);
[DllImport("dxva2.dll", EntryPoint = "SetMonitorBrightness")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetMonitorBrightness(IntPtr handle, uint newBrightness);
private uint _physicalMonitorsCount = 0;
private PHYSICAL_MONITOR[] _physicalMonitorArray;
private IntPtr _firstMonitorHandle;
private uint _minValue = 0;
private uint _maxValue = 0;
private uint _currentValue = 0;
public BrightnessController(IntPtr windowHandle)
{
uint dwFlags = 0u;
IntPtr ptr = MonitorFromWindow(windowHandle, dwFlags);
if (!GetNumberOfPhysicalMonitorsFromHMONITOR(ptr, ref _physicalMonitorsCount))
{
throw new Exception("Cannot get monitor count!");
}
_physicalMonitorArray = new PHYSICAL_MONITOR[_physicalMonitorsCount];
if (!GetPhysicalMonitorsFromHMONITOR(ptr, _physicalMonitorsCount, _physicalMonitorArray))
{
throw new Exception("Cannot get physical monitor handle!");
}
_firstMonitorHandle = _physicalMonitorArray[0].hPhysicalMonitor;
if (!GetMonitorBrightness(_firstMonitorHandle, ref _minValue, ref _currentValue, ref _maxValue))
{
throw new Exception("Cannot get monitor brightness!");
}
}
public void SetBrightness(int newValue) // 0 ~ 100
{
newValue = Math.Min(newValue, Math.Max(0, newValue));
_currentValue = (_maxValue - _minValue) * (uint)newValue / 100u + _minValue;
SetMonitorBrightness(_firstMonitorHandle, _currentValue);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_physicalMonitorsCount > 0)
{
DestroyPhysicalMonitors(_physicalMonitorsCount, ref _physicalMonitorArray);
}
}
}
}
Here is code that changes brightness in Windows's settings (suitable for laptops):
using System;
using System.Management;
public static class WindowsSettingsBrightnessController
{
public static int Get()
{
using var mclass = new ManagementClass("WmiMonitorBrightness")
{
Scope = new ManagementScope(@"\\.\root\wmi")
};
using var instances = mclass.GetInstances();
foreach (ManagementObject instance in instances)
{
return (byte)instance.GetPropertyValue("CurrentBrightness");
}
return 0;
}
public static void Set(int brightness)
{
using var mclass = new ManagementClass("WmiMonitorBrightnessMethods")
{
Scope = new ManagementScope(@"\\.\root\wmi")
};
using var instances = mclass.GetInstances();
var args = new object[] { 1, brightness };
foreach (ManagementObject instance in instances)
{
instance.InvokeMethod("WmiSetBrightness", args);
}
}
}
And here is code to change brightness and an external monitor(s) (but won't work for built-in ones like on laptops).
This code is modified version of @help's code that uses
EnumDisplayMonitors
instead ofMonitorFromWindow
, so it doesn't need window to run and searches for all monitors and not only for one window is on right now.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
public class PhysicalMonitorBrightnessController : IDisposable
{
#region DllImport
[DllImport("dxva2.dll", EntryPoint = "GetNumberOfPhysicalMonitorsFromHMONITOR")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetNumberOfPhysicalMonitorsFromHMONITOR(IntPtr hMonitor, ref uint pdwNumberOfPhysicalMonitors);
[DllImport("dxva2.dll", EntryPoint = "GetPhysicalMonitorsFromHMONITOR")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetPhysicalMonitorsFromHMONITOR(IntPtr hMonitor, uint dwPhysicalMonitorArraySize, [Out] PHYSICAL_MONITOR[] pPhysicalMonitorArray);
[DllImport("dxva2.dll", EntryPoint = "GetMonitorBrightness")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetMonitorBrightness(IntPtr handle, ref uint minimumBrightness, ref uint currentBrightness, ref uint maxBrightness);
[DllImport("dxva2.dll", EntryPoint = "SetMonitorBrightness")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetMonitorBrightness(IntPtr handle, uint newBrightness);
[DllImport("dxva2.dll", EntryPoint = "DestroyPhysicalMonitor")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DestroyPhysicalMonitor(IntPtr hMonitor);
[DllImport("dxva2.dll", EntryPoint = "DestroyPhysicalMonitors")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DestroyPhysicalMonitors(uint dwPhysicalMonitorArraySize, [In] PHYSICAL_MONITOR[] pPhysicalMonitorArray);
[DllImport("user32.dll")]
static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, EnumMonitorsDelegate lpfnEnum, IntPtr dwData);
delegate bool EnumMonitorsDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr dwData);
#endregion
private IReadOnlyCollection<MonitorInfo> Monitors { get; set; }
public PhysicalMonitorBrightnessController()
{
UpdateMonitors();
}
#region Get & Set
public void Set(uint brightness)
{
Set(brightness, true);
}
private void Set(uint brightness, bool refreshMonitorsIfNeeded)
{
bool isSomeFail = false;
foreach (var monitor in Monitors)
{
uint realNewValue = (monitor.MaxValue - monitor.MinValue) * brightness / 100 + monitor.MinValue;
if (SetMonitorBrightness(monitor.Handle, realNewValue))
{
monitor.CurrentValue = realNewValue;
}
else if (refreshMonitorsIfNeeded)
{
isSomeFail = true;
break;
}
}
if (refreshMonitorsIfNeeded && (isSomeFail || !Monitors.Any()))
{
UpdateMonitors();
Set(brightness, false);
return;
}
}
public int Get()
{
if (!Monitors.Any())
{
return -1;
}
return (int)Monitors.Average(d => d.CurrentValue);
}
#endregion
private void UpdateMonitors()
{
DisposeMonitors(this.Monitors);
var monitors = new List<MonitorInfo>();
EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, (IntPtr hMonitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr dwData) =>
{
uint physicalMonitorsCount = 0;
if (!GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, ref physicalMonitorsCount))
{
// Cannot get monitor count
return true;
}
var physicalMonitors = new PHYSICAL_MONITOR[physicalMonitorsCount];
if (!GetPhysicalMonitorsFromHMONITOR(hMonitor, physicalMonitorsCount, physicalMonitors))
{
// Cannot get physical monitor handle
return true;
}
foreach (PHYSICAL_MONITOR physicalMonitor in physicalMonitors)
{
uint minValue = 0, currentValue = 0, maxValue = 0;
if (!GetMonitorBrightness(physicalMonitor.hPhysicalMonitor, ref minValue, ref currentValue, ref maxValue))
{
DestroyPhysicalMonitor(physicalMonitor.hPhysicalMonitor);
continue;
}
var info = new MonitorInfo
{
Handle = physicalMonitor.hPhysicalMonitor,
MinValue = minValue,
CurrentValue = currentValue,
MaxValue = maxValue,
};
monitors.Add(info);
}
return true;
}, IntPtr.Zero);
this.Monitors = monitors;
}
public void Dispose()
{
DisposeMonitors(Monitors);
GC.SuppressFinalize(this);
}
private static void DisposeMonitors(IEnumerable<MonitorInfo> monitors)
{
if (monitors?.Any() == true)
{
PHYSICAL_MONITOR[] monitorArray = monitors.Select(m => new PHYSICAL_MONITOR { hPhysicalMonitor = m.Handle }).ToArray();
DestroyPhysicalMonitors((uint)monitorArray.Length, monitorArray);
}
}
#region Classes
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PHYSICAL_MONITOR
{
public IntPtr hPhysicalMonitor;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szPhysicalMonitorDescription;
}
[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
public int left;
public int top;
public int right;
public int bottom;
}
public class MonitorInfo
{
public uint MinValue { get; set; }
public uint MaxValue { get; set; }
public IntPtr Handle { get; set; }
public uint CurrentValue { get; set; }
}
#endregion
}
Just found the SetMonitorBrightness
function on MSDN.