Category Archives

Setting the device brightness on Windows with WPF

.NET, Technical stuff, Windows 10, Windows 7, Windows 8, Work, WPF
3 Comments

I am working on a project which I can’t really detail, but one aspect caused me a few headaches. Finally I reached out to the Windows team at Microsoft and got great help from Katie Anderson who works on the brightness team. This was quite tricky, and we had to have a couple of roundtrips before we managed to find a way that worked.

Well, why?

In the application I am working on, it is necessary for the user to set the device brightness from the application itself. You might wonder why, because most Windows devices have hard keys to set the monitor brightness. For example on a Surface, you can use the Fn-Del and Fn-Backspace key combinations to alter the brightness of the screen. Or you can of course swipe from the right side and use the Brightness button to change the value in the Action Center.

However on that particular project, the user doesn’t have access to the keyboard, nor to the Action Center. This is a kind of kiosk scenario if you will where many of the Windows features are deactivated by policies, and no hard keyboard is provided. I had to find a way to do this programmatically.

First approach: Not so good

At first I thought I would have my application’s main window run in full screen and set a black Rectangle on top of everything, and change the Rectangle’s opacity in my code. That worked well but of course it wouldn’t work if other applications were in the foreground (yes, I forgot to mention, it’s a kiosk app which can start other apps and put them in the foreground…).

Second approach: Better but not great

OK, no problems I thought, let’s have my app open a modal full screen window which is always on top. I will then have this window made insensitive to touch or mouse clicks with the following code. Finally, this window will have the black Rectangle and be on top of everything all the time.

public static class WindowsServices
{
    private const int GwlExstyle = -20;
    private const int WsExTransparent = 0x00000020;

    public static void SetWindowExTransparent(IntPtr hwnd)
    {
        var extendedStyle = GetWindowLong(hwnd, GwlExstyle);
        SetWindowLong(hwnd, GwlExstyle, extendedStyle | WsExTransparent);
    }

    [DllImport("user32.dll")]
    static extern int GetWindowLong(IntPtr hwnd, int index);

    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
}

This worked OK but somehow it was not satisfying. I really wanted to have a solution where my app would modify the actual device brightness. There are a few reasons why the client also wanted that, and so I started to investigate deeper. Unfortunately, Bing searches (and the equivalent Google searches) didn’t really return anything satisfactory.

Using Powershell

After searching a bit, I got a first clue that what I wanted to achieve was doable: You can query and modify the device brightness from Powershell with the following script:

CODE TO GET THE BRIGHTNESS INSTANCE

PS C:> Get-Ciminstance -Namespace root/WMI -ClassName WmiMonitorBrightness

CODE TO SET THE BRIGHTNESS

PS C:\Users\lbugn> $monitor = Get-WmiObject -ns root/wmi -class wmiMonitorBrightNessMethods
PS C:\Users\lbugn> $monitor.WmiSetBrightness(50,10)

If you run these commands in Powershell, you will marvel at the result: Yes it does work and the screen’s brightness is modified. Great Scott, I am on the right track! The key to this is the WMI (Windows Management Interface) class WmiMonitorBrightness.

Converting to .NET

The next step was obvious: I needed to convert the Powershell script to some usable .NET code. Unfortunately, easier said than done. This is where I reached out to Microsoft for help and thankfully Katie really followed through and after a few iterations we got it to work.

First she used the WMI Code Creator tool to convert the Powershell script to .NET. I had no idea that such a tool existed, but then again I never had to dive so deep in the entrails of Windows. Unfortunately when running the code that the tool created (which I won’t post here to avoid confusion), I got some errors. One more roundtrip to Redmond (via email) and Katie found the way: The following code will indeed modify the brightness of the screen, yay!!

public static class WindowsServices
{
    private static ManagementObject _brightnessInstance;
    private static ManagementBaseObject _brightnessClass;

    static WindowsServices()
    {
        // Querying the Windows service to get the Brightness API.
        var searcher = new ManagementObjectSearcher(
            "root\\WMI", 
            "SELECT * FROM WmiMonitorBrightness");

        var results = searcher.Get();
        var resultEnum = results.GetEnumerator();
        resultEnum.MoveNext();
        _brightnessClass = resultEnum.Current;

        // We need to create an instance to use the Set method!
        var instanceName = (string)_brightnessClass["InstanceName"];
        _brightnessInstance = new ManagementObject(
            "root\\WMI",
            "WmiMonitorBrightnessMethods.InstanceName='" + instanceName + "'",
            null);
    }

    public static int GetDeviceCurrentBrightness()
    {
        // Getting the current value.
        var value = _brightnessClass.GetPropertyValue("CurrentBrightness");
        var valueString = value.ToString();
        return int.Parse(valueString); // Direct cast fails.
    }

    public static void SetDeviceBrightness(int newValue)
    {
        if (newValue < 0)
        {
            newValue = 0;
        }

        if (newValue > 100)
        {
            newValue = 100;
        }

        var inParams = _brightnessInstance.GetMethodParameters("WmiSetBrightness");
        inParams["Brightness"] = newValue;
        inParams["Timeout"] = 0;
        _brightnessInstance.InvokeMethod("WmiSetBrightness", inParams, null);
    }
}

I made a small sample here which gets the current value of the screen brightness and then increases it by 10% every time you click on a button. When you reach 100%, it goes back to zero on the next click. Simple enough, and does the trick.

I hope that this will be useful to a reader looking for the same feature. I’d love to be the first one to ever blog about this. I doubt that I am, and probably someone will point me to the article that I never found :) but seriously, I really couldn’t find any mention of something like that on the whole WWW.

Happy coding!
Laurent

GalaSoft Laurent Bugnion
Laurent Bugnion (GalaSoft)

Share on Facebook
 

//build conference in Anaheim: Keynote notes #bldwin

.NET, Build, Technical stuff, UX, Windows 7, Work
No Comments

This post was imported from my old blog and had 2 comments which are included as a screenshot at the end of this post.

As usual when I attend a conference, I like to take quick notes to remember what it was all about and take some time later to analyze it. Since Windows 8 is going to be the next big things, let me share my notes with you!

Read the rest of this entry »

Installing Windows 7 from a USB drive

Technical stuff, Windows 7, Work
No Comments

This post was imported from my old blog and had 5 comments which are included as a screenshot at the end of this post.

Yesterday, Windows 7 RC (release candidate) was published on MSDN, so the subscribers are currently downloading it. I have been using Windows 7 since October 2008, when it was pre-released during the PDC conference. Then I moved to the beta when it was released, and have been using it as my main system since then. I almost never had to go back to Vista (which I kept installed on another partition of my main laptop, just in case).

Read the rest of this entry »

The #techdays presentations screencasts are online (French only)

.NET, Blend, IdentityMine, TechDays, Technical stuff, Windows 7, Work, WPF
No Comments
Update: The German version of the presentation is online too.

I was just notified that the screencast for the session I gave at TechDays in Geneva a few weeks ago is now online.

Read the rest of this entry »

Posting the source code for #techdays (Switzerland) talks

.NET, Blend, IdentityMine, TechDays, Technical stuff, Windows 7, Work, WPF
No Comments

This post was imported from my old blog and had 1 comments which are included as a screenshot at the end of this post.

Update:

I updated the installation instructions to make it clearer that you need the WPF toolkit and SQL Server express before you can run the application.

Read the rest of this entry »

IdentityMine releases Gesture Engine for advanced multitouch development

.NET, Blend, IdentityMine, Technical stuff, Windows 7, Work, WPF
No Comments

Multitouch is going to be the next big thing. Natural User Interfaces (NUI) are going to change the way we use client applications soon. You think it’s not true? See the iPhone hype. This is not a very good phone, feature wise. It is lacking very basic features. But being able to control your phone using multiple fingers was a real killer feature.

Read the rest of this entry »

Windows 7 beta 1 install experience

Technical stuff, Windows 7
No Comments

This post was imported from my old blog and had 5 comments which are included as a screenshot at the end of this post.

I’ve been an avid user of Windows 7 pre beta ever since we got a build at the PDC conference in Los Angeles in October 2008. I installed it in dual boot on my work laptop, as explained here. There were a few minor kinks that forced me to keep Vista on this machine. The most annoying was that it was impossible to debug Silverlight on that build. Well, happy to report that this annoying bug is gone now, and I can develop and debug Silverlight on Windows 7 now. Let’s see other problems and what happened to them:

Read the rest of this entry »

Weird color effect with Windows 7 and LiveMesh

Technical stuff, Windows 7, Work
No Comments

This post was imported from my old blog and had 6 comments which are included as a screenshot at the end of this post.

I’ve been testing Windows 7 in real life conditions for the past few weeks, and am happy to report that I didn’t need to fall back to Vista at all so far. There are a couple of very small details that bug me a little, but I am not even sure if they’re related to Win7, so I just live with them for the moment.

Read the rest of this entry »

One week at IdentityMine

IdentityMine, Personal, Technical stuff, Windows 7, Work
No Comments

Today is the end of my very first week at IdentityMine. Let me just say that it was really great. In the same week I worked on a proposal for a client (maybe our very first project in the new European IdentityMine, crossing fingers) and prepared a presentation for next week. I’ll be flying to Vienna, Austria on Wednesday morning and will go back home on Friday evening. I will demo various technologies that IdentityMine is working on, and I am really looking forward to that experience.

Read the rest of this entry »

Silverlight on Windows Update (Windows 7)

Silverlight, Technical stuff, Windows 7, Work
No Comments

This post was imported from my old blog and had 5 comments which are included as a screenshot at the end of this post.

Still busy setting up my Windows 7 partition. Just noticed that Silverlight was pushed to it through Windows Update. Cool.

Read the rest of this entry »