Ever since I started writing windows applications, even though most of them were not in C or C++, almost every time I would refer back to Charles Petzold’s Programming Windows. Whether it was Visual Basic, Delphi, .NET or even Java, there would eventually come a point, where the only way to achieve something would be to dig into the Win32 API and hook into the message loop directly.
I don’t know why I thought writing a WPF application in .NET 4 for Windows 7 would be any different.
If you start with a default empty window it is rendered nicely with a drop shadow around it (like all other windows).
However, I wanted to achieve an alternative layout, without the frame but with the shadow still on. Unfortunately setting
WindowStyle="None" creates a rather blunt rectangle.
There is always the option to do something inside the client window to pretend your window actually does have a shadow but it is somewhat messy and just not as pretty (or perhaps I wasn’t ready to tinker with the Canvas and Effects enough). So will say it also comes with a performance penalty (since you would require transparent background).
Finally, with a little bit of Interop spice by calling Desktop Window Manager APIs I got the desired effect:
Mind you it only works if DWM is available (that is in Vista and Windows7) but I’m fine with that.
Here is the required code:
[DllImport("dwmapi.dll", PreserveSig = true)]
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset);
void ShellWindow_SourceInitialized(object sender, EventArgs e)
var helper = new WindowInteropHelper(this);
int val = 2;
DwmSetWindowAttribute(helper.Handle, 2, ref val, 4);
var m = new Margins
bottomHeight = -1,
leftWidth = -1,
rightWidth = -1,
topHeight = -1
If you want to dig deeper there is WPF Shell Integration Library that does some of this heavy lifting for you.
P.S. Seems like Java folks have similar challenges.