tags:

views:

558

answers:

2

I would like to create a top-level (i.e., not WS_CHILD) window with transparency. However, I don't want it to be a simple mask, where a given pixel is either fully transparent or fully opaque. And I don't want it to be such that the entire window has some alpha level to it. Rather, I'd want the window to essentially be entirely transparent, with a bitmap drawn to it with an alpha channel, such that the bitmap blends with whatever windows may be behind it. Picture, say, a sunburst, where an image's own alpha blends from opaque to fully transparent outward from the center.

I have found two methods that both get close to what I want to do, but not quite. Using regions, I can cut out a section that is drawn completely transparent. Using layered windows, I can also do something similar (or can even make the entire window slightly transparent, but that is not what I want at all). I have looked into other styles, such as WS_EX_TRANSPARENT and WS_EX_COMPOSITE, but to no avail.

I can get this kind of effect to work just fine on child windows, since they are blending with their parent windows within their parent's region. Getting it to work similarly for top-level windows continues to elude me.

I know this can be done, as people have assured me they've seen it in other programs. I feel like I'm just not fully understanding something simple here about painting windows.

+2  A: 

Layered windows (WS_EX_LAYERED) should do the job, keeping in mind that you must use UpdateLayeredWindow() and a somewhat unusual bitmap format (32-bit, pre-multiplied alpha) to specify per-pixel alpha values (SetLayeredWindowAttributes() will only allow you to specify a single alpha value for the entire window or color key).

You say you've already tried this - what problems did you experience?

Shog9
My problem was I wasn't understanding how to use UpdateLayeredWindow correctly, and so didn't think that I needed it. The key was setting the blend function and giving it the right dc for the bitmap. So, got it working, thanks!
Doug Kavendek
+1  A: 

The only way I know of to get per-pixel alpha on a window is UpdateLayeredWindow().
Check out this MSDN link: http://msdn.microsoft.com/en-us/library/ms997507.aspx

Note that when using UpdateLayeredWindow the application doesn't need to respond to WM_PAINT or other painting messages, because it has already provided the visual representation for the window and the system will take care of storing that image, composing it, and rendering it on the screen. UpdateLayeredWindow is quite powerful, but it often requires modifying the way an existing Win32 application draws.

I bet these are the issues you were experiencing.

zildjohn01
For some reason, I had been ignoring UpdateLayeredWindow(), but looking more into it, I got it working. And luckily, I actually didn't even have to change how my app draws too drastically, since it only applied to certain specific windows.
Doug Kavendek