tags:

views:

565

answers:

1

Creating Glass window is as easy as calling DwmExtendFrameIntoClientArea in WPF, but that is only half of the trick. If you disable aero, and get the XP-like skin thats where the pain begins:

In XP (or disabled aero) you must call DrawThemeBackground in order to get "transparent like feel", Internet explorer does this too on its top, try disabling aero and look that.

I've cooked up application that does just that, fallback gracefully when Aero is disabled in Windows.Forms.

The question: But doing it in WPF is different, the OnRender (OnPaint equiv. in avalon) which gives you DrawingContext, how one draws on that with DrawThemeBackground WINAPI call?

+2  A: 

Well, DrawThemeBackground needs an device context handle, which is a pure Win32 concept... WPF doesn't use device contexts or window handles. However, a WPF app is hosted in a Win32 window, and you can retrieve the HWND of that window :

using System.Windows.Interop;

...

IntPtr hwnd = new WindowInteropHelper(this).Handle;

You can then obtain a DC for this window using the GetDC API :

[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr hWnd);

...

IntPtr hdc = GetDC(hwnd);

You should then be able to use DrawThemeBackground with this DC.

Note that this is all purely theoretical, I didn't test it...

Thomas Levesque
Right, thats what I initially tried also with begin paint etc. But I still couldn't paint to the DrawingContext. My Aero Glass WPF window extension (one blog entry before that) uses similar tricks, that works just fine, though no handling of HDC there.I think we should try instead DrawThemeBackground -> System.Windows.Media.Drawing -> System.Windows.Media.DrawingBrush, and use DrawingContext.DrawRectangle(ourDrawThemeBackgroundBrush, ...) in OnRender override but I haven't wrapped myself around that yet.
Ciantic
Perhaps you could create an image of the correct size, get a DC for it (with `Graphics.FromImage`), call `DrawThemeBackground` on this DC, and draw the image in your DrawingContext... but I'm not sure how it will work, it could cause performance issues
Thomas Levesque
If we could make "a clean" Graphics object where to draw, and convert it to Drawing... I'll try that. Drawing to existing Graphics is well, same as in my Forms thing, so the problem probably boils down to converting it to Drawing/DrawingImage.
Ciantic
You can't "convert" it, because WPF is completely unrelated to GDI+. But as I explained in my previous comment, you can use the graphics to draw the background on an image, and draw the image on the DrawingContext.
Thomas Levesque