ALPHA-Channel Problems

tyonuts

Well-known member
Joined
Dec 27, 2005
Messages
78
Location
Romania
Programming Experience
3-5
I know I posted more than one question on this issue, but ever-since the 32 bit graphics were invented, it keeps giving me headaches. So here's my latest question:

I created a very very simple application, which consists in a translucent form with some text and images on it (labels, pictureboxes). The way i did it: just set the form's opacity to a value lower than 100%.

How can I display parts of the form with the given opacity, while others are 100% opaque? In other words, how can I get my text and images to be COMPLETELY opaque, while the form is still translucent? Is this even possible in .NET?

Please note the idea came from the interface of Stardock's DesktopX (but I guess that's made in C++), which did exactly this thing. Any ideas?:confused:
 
I have not done what you are talking about but I assume you could override the onpaint event of the controls.... actually try for the form first, then if that doesnt work try a control.

VB.NET:
Protected Overrides Sub OnPaint(e As PaintEventArgs)
     MyBase.OnPaint(e)
     e.Graphics.DrawString(Text, Font, New SolidBrush(ForeColor), RectangleF.op_Implicit(ClientRectangle))
End Sub
 
I have sat here thinking about this for about half an hour or so and yes i definately think it is possible, though i don't think it will be easy.

First what i think you need to do is create a layered window by setting it's WS_EX_LAYERED extended style bit. To do this you'll need to get the windows current styel bit using the GetWindowLong function then you can set it's GWL_EXSTYLE flag. Once you have accomplished that you then need setlayeredwindow API. Pass it the handle to the window and the alpha value you want. There is one catch, and that is that your window must be a top level window.
 
Shroomy, your solution isn't even close to what I need. And I will tell you, that was the first trick i tried when i thought about it. Thanks anyway.

It IS a top level window. Thanks a lot vis781. But I was wondering if there were another way than creating a normal window (through WinAPI), because i don't think i can use those same properties on a System.Windows.Forms.Form object. Anyway, can you give me any links to some good documentations about WinAPI (except MSDN)?
 
I've just looked a bit deeper into this and i'm not so sure now that my idea will work. I mean, it will but it may make the whole form transparent including any child controls mmmm I havent got time not but you may be able to combine my above idea with the setwindowrgen API it's gives the ability the set a specific region of a window to a transparent/translucent color.
 
before you go the api route, have you tried overriding the textrenering class? which would be nice since you can set it for the whole application and not for each form or element.

It seems like if you did and just converted the text to its bitmapped representation it would be straightforward. (since the bitmapps would lose their transparancy)


but if you do need to loop through the controls after the form is drawn (say on form load) and redraw the text this snippet may help

here is how to get the handles of all the controls, sorry I dont know the api you need for the rendering .. but i dont think the setwindowrgen would work since it works with rectangles not the text.



VB.NET:
just set an arraylist  = GetChildWindowHandles(me.handle)
loop through the arraylist and call the api to rerender the text for each handle
 
[SIZE=2][COLOR=#0000ff]Public[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Declare[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Auto[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Function[/COLOR][/SIZE][SIZE=2] GetWindow [/SIZE][SIZE=2][COLOR=#0000ff]Lib[/COLOR][/SIZE][SIZE=2][COLOR=#800000]"user32.dll"[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] hWnd [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] IntPtr, [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] uCmd [/SIZE][SIZE=2][COLOR=#0000ff]As [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Long[/COLOR][/SIZE][SIZE=2]) [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] IntPtr[/SIZE]
[SIZE=2][/SIZE] 
[SIZE=2] 
[/SIZE]
[SIZE=2][COLOR=#0000ff]Public[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Function[/COLOR][/SIZE][SIZE=2] GetChildWindowHandles([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] ParentWindowHandle [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] IntPtr) [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] ArrayList
[/SIZE][SIZE=2][COLOR=#0000ff]    Dim[/COLOR][/SIZE][SIZE=2] ptrChild [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] IntPtr = GetChildWindowHandle(ParentWindowHandle)
[/SIZE][SIZE=2][COLOR=#0000ff]    Dim[/COLOR][/SIZE][SIZE=2] clsRet [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] ArrayList
[/SIZE][SIZE=2][COLOR=#0000ff]    Do[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Until[/COLOR][/SIZE][SIZE=2] ptrChild.Equals(IntPtr.Zero)
        clsRet.Add(ptrChild)
        ptrChild = GetNextWindowHandle(ptrChild)
[/SIZE][SIZE=2][COLOR=#0000ff]    Loop
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]    Return[/COLOR][/SIZE][SIZE=2] clsRet
[/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Function
[/COLOR][/SIZE]
 
thanks for the code and the effort, but i don't think this is something to be set by overrideing some .NET functions. If the main parent itself is a .NET component (in this case, System.Windows.Forms.Form), then the property applies to all it's children. I guess vis781 might be right, because a normal WinAPI window is very different, compared to a .NET one, it might allow such transformations.
Besides, the bitmap would also be displayed at the same level of opacity the form has.
I will try your solution though; thanks for the help man.
 
Back
Top