[Note: this is ported from my old blog, and there’s more discussion there.]
All the cool kids these days are playing with awesome dynamic languages, or on cool frameworks. I’m stuck with c++ at work, but every now and then I get to do something cool with it.
That’s the Wacom radial menu, which is implemented as a fully alpha-blended window in native Win32. Something like this is dead simple in WPF, but with native code it’s a bit trickier. I used WTL, GDI+, and a handy, little-known Windows feature to get it done, and I’m going to share my secrets with you, dear reader.
Windowing frameworks are thick on the ground, and I’ve been mostly dissatisfied with the abilities of the Win32-wrapping category. However, they make something like this reusable, so what the heck.
You can grab WTL at the project home on
SourceForge. For this project, I’m just taking
the files in the
include directory and putting them under
wtl in my project
directory, so I don’t get the Windows SDK versions instead.
I’ve found this to be the best way to include the WTL headers:
Those defines specify that the ATL and WTL classes should stay safely ensconced
in their own namespaces. This means you have to reference them as
WTL::CFrameWndImpl, but it keeps the global namespace clean, which is a major
GDI+ is an immediate-mode drawing API that has shipped with Windows since XP, so I can use it without needing to ship yet another redistributable installer. Here’s all you need to do:
While GDI+ is written in c++ and uses classes, it’s initialization isn’t RAII-friendly, so I wrote a little wrapper class:
Now I can write my main function like this:
The production code for this feature uses boost (specifically
but in the interest of simplicity I’ve left it out. If you use boost, or your
compiler supports the new
std::shared_ptr introduced with TR1, I highly
recommend you use that instead of raw pointers whenever possible.
A window class
Here’s where it all comes together. Meet me after the code, and I’ll explain more fully.
The magic ingredients for this class are the
WS_EX_* styles and the
First, the styles. These are specified on line 3, as part of the base class. That’s just how you declare your window’s styles in WTL. There are two:
WS_POPUPmeans this is a square window with no decorations around the outside. No title bar, no close button, nothing.
WS_EX_LAYEREDtells Windows that this window is different, and that it can do per-pixel alpha blending with other windows. This was available in Windows 2000, but starting with Vista the window’s face could be cached and composited by the GPU, which made it much more useful.
The call to
UpdateLayeredWindow on line 35 is what tells Windows what the
contents of the display are. There’s some clunky interop code here, since the
Bitmap object can’t be used directly with the GDI-oriented layered
window API. I’m sure there’s a better way, but in my case the overhead of
copying my smallish
Bitmap into another smallish
HBITMAP wasn’t a problem.
WTL complains rather loudly if a window object is destroyed before the HWND it’s wrapping is closed, so the destructor on line 7 takes care of that.
UpdatedLayeredWindow call is wrapped in a method that takes a GDI+
bitmap, so now all we need to do is provide it with one. GDI+ makes this pretty
easy, especially when compared to GDI code:
All together now
main function of my little test program.
I know, programmer demos of this are always ugly. Maybe one day I’ll write about how to store a PNG as a resource, and load it in for use with this. For now, you get an ugly screenshot: