How do I adjust the screen brightness in 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 phisical 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 PhisicalMonitorBrightnessController : 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 PhisicalMonitorBrightnessController()
{
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 phisical 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
}
Actually you can use SetDeviceGammaRamp()
to set the screen brightness in C#.
Create a new windows form application and copy the following code. Just drag a trackbar and a button to the windows.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace brightnesscontrol
{
public partial class Form1 : Form
{
[DllImport("gdi32.dll")]
private unsafe static extern bool SetDeviceGammaRamp(Int32 hdc, void* ramp);
private static bool initialized = false;
private static Int32 hdc;
private static int a;
public Form1()
{
InitializeComponent();
}
private static void InitializeClass()
{
if (initialized)
return;
hdc = Graphics.FromHwnd(IntPtr.Zero).GetHdc().ToInt32();
initialized = true;
}
public static unsafe bool SetBrightness(int brightness)
{
InitializeClass();
if (brightness > 255)
brightness = 255;
if (brightness < 0)
brightness = 0;
short* gArray = stackalloc short[3 * 256];
short* idx = gArray;
for (int j = 0; j < 3; j++)
{
for (int i = 0; i < 256; i++)
{
int arrayVal = i * (brightness + 128);
if (arrayVal > 65535)
arrayVal = 65535;
*idx = (short)arrayVal;
idx++;
}
}
bool retVal = SetDeviceGammaRamp(hdc, gArray);
return retVal;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
a = trackBar1.Value;
SetBrightness(a);
}
}
}
Maybe you need to change the max and min value of the trackbar.
You can follow the tutorial here. More pictures and details: http://www.lattepanda.com/topic-f11t3020.html?sid=f9dc5d65cd4f2feb3c91ca41196c087e
Just found the SetMonitorBrightness
function on MSDN.
I tested the below code on my tablet and laptops work. You need to add a reference System.Management, find in the NuGet. This changes the actual brightness of the monitor.
//get the actual percentage of brightness
static int GetCurrentBrightness()
{
//define scope (namespace)
System.Management.ManagementScope s = new System.Management.ManagementScope("root\\WMI");
//define query
System.Management.SelectQuery q = new System.Management.SelectQuery("WmiMonitorBrightness");
//output current brightness
System.Management.ManagementObjectSearcher mos = new System.Management.ManagementObjectSearcher(s, q);
System.Management.ManagementObjectCollection moc = mos.Get();
//store result
byte curBrightness = 0;
foreach (System.Management.ManagementObject o in moc)
{
curBrightness = (byte)o.GetPropertyValue("CurrentBrightness");
break; //only work on the first object
}
moc.Dispose();
mos.Dispose();
return (int)curBrightness;
}
//array of valid brightness values in percent
static byte[] GetBrightnessLevels()
{
//define scope (namespace)
System.Management.ManagementScope s = new System.Management.ManagementScope("root\\WMI");
//define query
System.Management.SelectQuery q = new System.Management.SelectQuery("WmiMonitorBrightness");
//output current brightness
System.Management.ManagementObjectSearcher mos = new System.Management.ManagementObjectSearcher(s, q);
byte[] BrightnessLevels = new byte[0];
try
{
System.Management.ManagementObjectCollection moc = mos.Get();
//store result
foreach (System.Management.ManagementObject o in moc)
{
BrightnessLevels = (byte[])o.GetPropertyValue("Level");
break; //only work on the first object
}
moc.Dispose();
mos.Dispose();
}
catch (Exception)
{
MessageBox.Show("Sorry, Your System does not support this brightness control...");
}
return BrightnessLevels;
}
static void SetBrightness(byte targetBrightness)
{
//define scope (namespace)
System.Management.ManagementScope s = new System.Management.ManagementScope("root\\WMI");
//define query
System.Management.SelectQuery q = new System.Management.SelectQuery("WmiMonitorBrightnessMethods");
//output current brightness
System.Management.ManagementObjectSearcher mos = new System.Management.ManagementObjectSearcher(s, q);
System.Management.ManagementObjectCollection moc = mos.Get();
foreach (System.Management.ManagementObject o in moc)
{
o.InvokeMethod("WmiSetBrightness", new Object[] { UInt32.MaxValue, targetBrightness });
//note the reversed order - won't work otherwise!
break; //only work on the first object
}
moc.Dispose();
mos.Dispose();
}
Above Got from: https://www.codeproject.com/Articles/236898/Screen-Brightness-Control-for-Laptops-and-Tablets