|
When a form is made transparent using the Opacity property, controls on the form still work like normal. They receive clicks, they draw themselves, etc. How does the framework support this?
|
|
|
|
|
Well, re-read my reply. Windows does not support this so my code does not support it either; if you want to add regular controls you have to roll you own solution.
----
Rui Lopes
|
|
|
|
|
Rui, what does this mean? "Or <<other solution="" here="">>!"
Overall this is an interesting technique but it has many limitations. Not being able to directly draw on the form is obviously a pain. The technique I am going to use is to have the source image, draw it to an "active" image, make modifications as required (button state, focus rectangles, etc.) and use that with SetBitmap. Hopefully this will be flicker-free assuming I am not updating the UI every 10 ms. I have no idea how this is going to perform, but in a few hours I'll let you know.
What I have done is take your basic technique and created a 'generic' Skinnable form that allows the user to define control regions, state images for those control regions, proper mouse handling (non-trivial), enabling/disabling, visibility, IsTabControl, TabIndex, Key processing, etc... My goal is to be able to drive all this from an XML definition for the Skinnable form.
I think most people would want to place actual controls (such as Button) directly on top of the skin, but to me this is limiting. Instead I am going for the light-weight controls (non-.NET) and doing all the processing myself. What I need is a good technique for drawing on the skin. Drawing on the bitmap directly seems like the best technique for me assuming decent flicker-free performance. For others, the layered window approach might be best.
Tom
|
|
|
|
|
Please let me know how this works for you. I guess -- after reading the comments -- that's what i am going to have to do and you could save me a lot of time if it doesn't work ... Thanks for the help!
|
|
|
|
|
I forgot to post the results of my tests. It works great, and performance seems very acceptable. I tend to work on higher end machines so your mileage may vary. I tested on XP Pro and Win2K. No problems at all.
I am in the process of setting up a general purpose "skin" form that handles all the regions, mouse/keyboard processing, events, etc. for psuedo-controls on the skin. I.e, you have a skin, define regions, create "controls" for those regions and all the drawing (states), mouse/keyboard, focus, etc. is handled by the "skin" form and forwarded as appropriate to the controls. In essence it is like a Win Form with standard controls, but skinned and without using actual Win Form controls. I am not sure it is the best technique. Someone else may provide a mechanism to use the layered window technique with a windows form overlayed with normal buttons, sliders, etc. I simply find the technique interesting and flexible.
It is up and running and is working fabulously, but I am using it for a special project that does not currently do everything you would want the general purpose "skin" form to do. Ergo, I need a different example that really pushes it. Maybe a "skin" form around the Windows Media Player control would be a interesting sample.
Tom
|
|
|
|
|
One solution is to send a WM_PRINT message to the base window along with the PRF_CHILDREN|PRF_CLIENT flags on a timer. You'll have to specify the memory HDC of the bitmap. This does not, however, help with edit controls, since the cursor will not draw properly. You'll have to add yet another hack to this hack. Not sure how to do this in C# though.
|
|
|
|
|
I am having the same problem. Please help!!
|
|
|
|
|
Has anyone found a solution to this yet?
|
|
|
|
|
Is anyone found a solution how to add controls?
|
|
|
|
|
So far (and as has been said before) with UpdateLayeredWindow your window will look like the bitmap you pass to that function. PERIOD.
So, how to draw controls? I figure out that my onwer drawn buttons were still receiving messages (even OnDraw) in response to their custom mouseover or pressed status, so my approach was to draw them on the window bitmap (do not draw on the DC passed with OnDraw, that will draw nothing) and then UpdateLayeredWindow to reflect changes (everytime there was a change, of course).
This approach is very easy to implement and works great. I've derived another controls starting from an owner draw CButton (checkboxes, etc) and the static controls were drawn before-hand on the bitmap. It works for a dialog with only some buttons, you can even create custom controls derived from a owner draw CButton or display images easily.
If you want a fully functional GUI, well... having in mind that you are basically drawing everything to a framebuffer and that you always have to update the whole window, the best option might be to design a new custom GUI with their own controls, or use something like PicoGUI. Whatever you do, do not forget that the point here is to have a very nice looking window alpha blended per-pixel with the desktop, not to reinvent a GUI inside another GUI
Hope this helps ^^
|
|
|
|
|
hello roy,
Thanks for the detailed answer. sound to me that this is the solution though my .net programming experience wouldn't allow me to build that from scratch.
Would you be able to send me a snippet code just to see a code example of this amazing technique working?
Thanks in advance,
Assaf
don't worry, be happy!
|
|
|
|
|
I just stumbled across this thread, but it seems there's still some interest. My solution was to add normal controls at design time, and then loop through them on Form_Load using AddHandler to point their MouseDown, MouseUp, MouseEnter, and MouseLeave events to a sub that draws them to a fresh copy of my source background image and updates the window with it. It seems to work fairly smoothly for a normal number of controls. The size of the window doesn't seem to matter all that much, either.
Since without this the controls can still be used (if not seen), an interesting idea is to simply draw whatever you like where the controls are located... so you get the built-in functionality of the System.Windows.Forms controls, but you can draw them as you see fit instead. Granted this only works with simple controls such as buttons and checkboxes. No point reinventing the wheel. I mean, who wants to rewrite the TreeView or ListView controls?
|
|
|
|
|
If we write bellow codes -
#define WINVER 0x0500 // this is needed for UpdateLayeredWindow
#define _WIN32_WINNT 0x0500 // this is needed for the WS_EX_LAYERED
in StdAfx.h for using Alpha blending, then CFileDialog will not be available.
Do you know some good idea?
|
|
|
|
|
Why not use OpenFileDialog that is part of the .Net framework?
Jared Bienz
jbienz@hotmail.com
|
|
|
|
|
I think it would be cool to have a window that has a title bar that is opaque but a client area that is translucent but text on that client area would be opaque.
Any idea how to do this?
Thanx
|
|
|
|
|
Well, if you are saying that you “just” want to make all NC areas alpha-blend and leave all your dialog controls as-is, no you can’t... well, you can... but you have to roll your own solution, because with alpha-blend windows, Windows caches the window bitmap and you have to manually update portions of the window where you have your controls, for example, if you have a button, you have to manually update the region where the button lays when that button changes state (i.e. pressed to not pressed).
----
Rui Lopes
|
|
|
|
|
Is there a way to make this work on Windows 98 and ME ?
|
|
|
|
|
No, Layered Windows are only supported on win2k or later.
----
Rui Lopes
|
|
|
|
|
I know that, but I asked if there is a way of doing it on Win98/ME without layered windows. Kai Power Tools and other similar applications have windows with drop shadow/alpha blendling which runs on Win98 too.
|
|
|
|
|
Yes, but I'm allmost sure that they all "fake" the shadow, for example, you can capture the screen region where the shadow will be placed to a bitmap, then alpha-blend the shadow with the captured bitmap, then show that bitmap in your window border or in a window placed at the your window edge.
But this aproach has it's problems, for example, if the window underneat the shadow changes the shadow does not reflect that change.
The applications that you are talking about make a full windows transparent? Or they just do that with shadows?
----
Rui Lopes
|
|
|
|
|
They have drop shadows for non-rectangular windows, and you can drag the window with the mouse, and the shadow changes.
I think that this is possible with GDI+ very easy with DrawImage and a CachedBitmap, DrawImage from GDI+ supports drawing a PNG file with alpha blending directly, but I still don't know if there is an easy way of painting back the background (if you drag the window).
|
|
|
|
|
Yes, GDI/GDI+ does the alpha-blend for you, but the question here is, Do they "fake" the shadow?
Have you move the window underneat the shadow? (not the window that has the shadow) Well, try this, open an animated gif and place the window that has a shadow on top of the animated gif and see if the shadow get's updated, If it get's updated I have to see that!
----
Rui Lopes
|
|
|
|
|
I'll try to use that feature in my next version (in C#) of NovaClock! Thanx!
(Best Regards,)
Patrick Hoffmann
-------------------------------------------------------------------------------
Technical and Operations Manager, System Analyst, Software Architect
PGP: http://www.novacom.net/pgp/PatrickHoffmann.asc
-------------------------------------------------------------------------------
veturo, der kostenlose NOVACOM Routenplaner für Europa... http://www.veturo.de
--------------------------------------------------------------------------
|
|
|
|
|