[.net] overriding OnPaint*...

Started by
3 comments, last by Cybrosys 18 years, 9 months ago
I checked out some nice longhorn shots and descided that i'd make part of my app transparent, unfortunately i haven't found a smart way to do this. Sure a form has it's opacity variable but that variable is set for the entire form and changing it during Paint messages didn't give me the results i wanted. First off, i've overriden both the OnPaint and OnPaintBackground message, cancelling em out but the titlebar still gets drawn, is there some way for me to alter the way it's drawn? Some longhorn screenshots, my first idea was simple, i'll override the title draw call (which doesn't exist?) and set the Opacity to something else than 1 and then set it back to 1 when the rest of the controls etc is drawn. The problem with opacity is that it's inherited to every control added to the form. Any comments on getting what longhorn looks like? Each app window would consist of 2 forms, each running in it's own thread. The first form would have the opacity set to 50% or something, the other form would always be located over the first form but with 100% opacity.
Advertisement
If I understand you correctly, you're trying to paint a form with different areas having a different opacity, and you're using Windows.Forms, not an Avalon CTP.

If I'm right, you're in for troubles. Win32 support for transparency is *very* limited. The technology behind the Opacity property is called Layered Windows. Look at the linked article, it's an excellent introduction.

Windows Forms only exposes a very small subset of what is possible with this API. The Opacity property sets the global opacity of your Form. Internally, it's rendered to a buffer, and the Layered API composes your screen by blitting this buffer using the provided transparency. If you've understood the previous sentence, you now realize why trying to change the Opacity property during the paint event doesn't work. If you want to know more about what .NET makes, look for SetLayeredWindowAttributes in MSDN. It's the function that .NET uses to achieve that effect.

The layered API does support different alpha transparency for different areas of your Form, though. But .NET doesn't expose this. You'll have to set it manually using Interop, the most important function here being: UpdateLayeredWindow. But that's going to be quite some work, with very little reward.

In conclusion, it's not without reasons that Ms is dropping Win32/GDI for a new API (WinFX/Avalon). What's possible with Win32 is just too limited, and for some things, you probably are better off waiting for Avalon to be available (next year, hopefully).

Regards,
jods
Winamp has done what you want for a very long time now. There are articles out there on simular things I've seen but I could not quickly find them on our fav friend Mr. Google. I leave my winamp at 70% transparent so I can read sites under it, etc. If I find the links later today I'll post them for you.

I'm pretty sure I found them on: www.codeproject.com

But the MSDN article is exactly what winamp looks like for me... So that might work also.

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

If you want parts of your form to be 'fully' transparent over the desktop you can set the TransparencyKey property to some color you are unlikely to use. Portions of your form painted with this color will be fully transparent over the desktop. I think that it is rather hacky myself, but it does work with some tweaking.
Thanks jods, the information you posted got me searching for Avalon etc and that lead me to some other nice articles etc on msdn aswell on Avalon, been a while since i've had a good read.

And about the colorkey, i know that exists, but if it, along with OnPaint worked as i wanted, i would have colorkeyed the entire background and then painted a gradient fill over it with Alpha to 50% or something, unfortunately that doesn't work.

This topic is closed to new replies.

Advertisement