Transparent controls in native WM apps

PegNosePete

New member
Oct 22, 2009
2
0
0
Hey all,

I've been searching for techniques people use to make transparent controls. The problem with windows mobile is that windows always have the CLIPCHILDREN window style set. So you can't grab the contents of the parent window (in WM_ERASEBKGND for example) because it isn't there.

One technique would be to have the parent pass the handle of the background DC it uses to the child control but that involves having a memory DC around all the time. And if the child control is covering any sibling controls you'd be out of luck as well.

Another solution I've read about is to temporarily hide the child window so the parent window is forced to redraw the parts that would normally be obscured by the control. I personally do not like this approach. (the drawbacks are also discussed on some MS forum, i'm not allowed to post outside links yet, google for "Rounded Buttons : Does any one see any problems with this method" and you will find it)

So, there are ways to achieve what I'm looking for but they are far from optimal. Just wondering what everybody else is doing to achieve this.
 

Chainfire

Moderator Emeritus / Senior Recognized Developer -
Oct 2, 2007
11,428
87,629
263
www.chainfire.eu
The responses in that thread are pretty much spot on (funny to find I know over half the posters in that thread by reputation).

If you want to do this well, you really need to draw your own stuff, making a complete custom UI.

There is no proper way to do this in Windows Mobile (without runtime kernel patching, that is :p).
 

PegNosePete

New member
Oct 22, 2009
2
0
0
The responses in that thread are pretty much spot on (funny to find I know over half the posters in that thread by reputation).

If you want to do this well, you really need to draw your own stuff, making a complete custom UI.

There is no proper way to do this in Windows Mobile (without runtime kernel patching, that is :p).
What do you mean by "drawing your own stuff"? I am drawing everything myself now in all control i made using AlpheBlend() where needed. But that still doesn't resolve the background issue. Or are you referring to just drawing everything in a single WM_PAINT handler and only having one screen DC?
 

Chainfire

Moderator Emeritus / Senior Recognized Developer -
Oct 2, 2007
11,428
87,629
263
www.chainfire.eu
What do you mean by "drawing your own stuff"? I am drawing everything myself now in all control i made using AlpheBlend() where needed. But that still doesn't resolve the background issue. Or are you referring to just drawing everything in a single WM_PAINT handler and only having one screen DC?
Well the method I use in my own new UI's is indeed per form (excluding WinAPI controls like edit boxes and such) draw using only one DC.

The problem is that any 'windowed' control, the parent will not draw to the DC if a 'windowed' control overlaps. Due to CLIPCHILDREN all data drawn to that position is simply lost.

Now, handling WM_PAINT you can get the entire update region, which tells you which parts of your form have to be redrawn. You must use this information, because blitting the entire form is very slow!

In essence, to do this right you well end up faking most of the GDI system, including your own 'fake' child windows, invalidating and revalidating portions, calculating the intersections of your 'fake' invalidated regions of the screen with the update region you get in WM_PAINT and redrawing those parts.

There are several different strategies to go about this, one is to redraw on demand, another one is to use double buffering.

I personally mostly use the double buffering technique, as this easily provides every 'fake' control with a bitmap of it's own region. A child control can then alphablend using the parent's buffer as one of the alphablend sources.

You can of course combine this with keeping state information whether a child, grandchild, etc is using alpha / transparency and this with an algorithm deciding which control needs double buffering or can draw on-demand, which can give both speed and memory use advantages. In a lot of situations you can then suffice with only double buffering the 'top' component (form) and a select number of child components.

Of course two drawbacks of per-control double buffering are speed and memory use. You can eliminate the complete-form double buffer with some smart coding and calculating. This will give you a slight speed and memory advantage. Memory use is high because many of your controls will have a copy of their current state.

This can be as complicated, feature-filled, fast and efficient as you are willing to make it. The better you can design the code the better it will work, but it is not a trivial task. There are many ways to go at this, no one way is definitely better than the other ways. It depends on what your applications does with it's display, how simple you are drawing (are you making a simple white background, or a background based on images for example gradient?), which method is more efficient.

The other method is getting the update region and actually perform redrawing of those invalidated sections (instead of copying from buffer). I can tell you from experience that if you are using image backgrounds and alphablend calls, this will be _much_ slower than double buffering (if done right).

I know all of this probaby makes little sense, I'm not a hero with explaining things ;)... you really have to figure this out for yourself, I guess.

Other advantages of building your own UI system are that if you do it smartly and buffering, it is very easy to port to directdraw, and possibly even GL. But I must warn you, on far the most devices actually using directdraw for this stuff is not much faster, it is in fact hardly noticable. If you manage to make a GL port, that can especially on older HTC devices (pre-HD2) be much faster.
 
Our Apps
Get our official app!
The best way to access XDA on your phone
Nav Gestures
Add swipe gestures to any Android
One Handed Mode
Eases uses one hand with your phone