17 Sep 2016 @ 3:42 PM 

Previously I wrote about implementing a Alpha-blended form with VB.NET. In that implementation, I had an abstract class derive from Form and then the actual forms derive from that. This causes issues with using the Form in the designer.

In order to workaround that issue I’ve redone parts of the implementation a bit to get it working as it’s own separate class. Rather than rely on the CreateParams() to adjust the GWL_EXSTYLE when the form is initially created, it merely uses SetWindowLong() to change it at runtime. Otherwise, the core of what it does is largely the same- just refactored into a package that doesn’t break the designer.

It should be noted, however, that adding controls to the form will not function as intended, though- this is inherent in the Alpha Blending feature, as it effectively just draws the bitmap. This is why it works well for Splash Screens. Controls will still respond to events and clicks however they will be invisible; making them visible would require drawing them onto the Bitmap and then setting it as the new Layered Window bitmap each time controls change.

Here is the changed code:

In usage it is no more complex than before, really:

The end result is largely the same:


Posted By: BC_Programming
Last Edit: 15 Oct 2016 @ 01:51 PM

EmailPermalinkComments Off on Alpha-Blended Forms revisited
 20 Jan 2013 @ 8:14 PM 
Note: This Post has been (partly) superceded by the implementation described in the more recent Alpha blended forms revisited Post.

One common problem that comes up in the creation of stylized windows such as Splash screens is the desire to have parts of the form be “shadowed” or, in other words, blend with the forms behind them. You can see this effect in action with other application splash screens, such as photoshop:

Photoshop Splash Screen in front of a dead-sexy website

Photoshop Splash Screen in front of a dead-sexy website

What witchcraft is this? How does Photoshop do it? One of the first things you might try with .NET is something like the TransparencyKey of the form. Of course, this doesn’t work, instead you get this unsightly ring of the transparency key around it.

The solution, of course, is a bit more complicated.

Starting with Windows 2000, the Win32 API and Window Manager has supported the idea of “layered” Windows. Before this, Windows had concepts known as “regions”; this basically allowed you to define regions of your window where the background would show through. This didn’t allow for per-pixel blending, but that sort of thing was not widely supported (or even conceived of, really) by most graphics Adapters. The “Layered” Windowing API basically provided a way to allow Per-pixel Alpha. Which is what we want.

Windows Forms, however, does not expose this layered window API through it’s methods or properties, with the exception of the opacity property. I don’t recall if WPF does either, but I would be surprised if it’s capabilities exposed more of the Layered Windowing API. Basically- we’re on our own

So what exactly do we need to do? Well, one thing we need to do is override the CreateParams property of the desired form, so that it adds the WS_EX_LAYERED style to the window, letting the Windowing Manager know it has to do more work with this window. Since we would like a neatly decoupled implementation, we are going to create a class that derives from Form, but use that as the base class for another form. This let’s us override the CreateParams property within that base class, but this has a bit of a caveat as well, since I’ve found that makes the Designer a bit annoyed and it complains and won’t let you use the designer. So you will have to deal with that particular point yourself. (I imagine there is a way to make it work, but I don’t want to bloat the class with such functionality). If necessary, the appropriate functions and the CreateParams override can be put into the classes that need this functionality instead.

Here is the PerPixelAlphaForm class. By the way, I’m going with Visual Basic.NET because there are already a million hits for this functionality with C#:

This provides the core implementation. The “Win32” class here provides the needed API declarations.

In order to use this, we need to make our form derive from it, and then use the inherited SetBitmap function:

(Here I just used an image on my second Hard disk that had a transparency channel, but the Bitmap constructor parameter can easily be changed.). The result:

The code in action

The code in action:

The Project I used for this can be downloaded from here. This was created using Visual Studio Professional 2012, Update 1- other editions or earlier versions may have problems with the project or source files.

Posted By: BC_Programming
Last Edit: 17 Sep 2016 @ 03:46 PM

EmailPermalinkComments (13)

 Last 50 Posts
Change Theme...
  • Users » 47469
  • Posts/Pages » 391
  • Comments » 105


    No Child Pages.

Windows optimization tips

    No Child Pages.

Soft. Picks

    No Child Pages.

VS Fixes

    No Child Pages.

PC Build 1: “FASTLORD”

    No Child Pages.