OS Composed DropShadows on WPF Windows with Custom Chrome

855 views
Skip to first unread message

Jeremiah Morrill

unread,
Aug 3, 2010, 1:39:26 AM8/3/10
to wpf-di...@googlegroups.com

I’m working on a WPF application and came across something that was hair-pulling.  I couldn’t find anything on google about it and thought to share so others wouldn’t have to go through the pain.

 

In this application, the main window needs custom chrome (min, max, restore buttons, resize borders, etc).  So I set about giving the WindowStyle a “None” value and the ResizeMode property to “NoResize”.  Then I noticed that you lose the drop shadow the DWM provides!  Ok, so naturally I just wanted to do an AllowsTransparency = True and add my own drop shadow…but AllowsTransparency has such atrocious performance (sad, huh?), it wasn’t an option for me.

 

Took a lot guess and checking, but here’s a snippet to get back your drop shadow on your window w/o sacrificing performance:

 

Image without code:

 

Image with code:

 

[StructLayout(LayoutKind.Sequential)]

public struct Margins

{

    public int leftWidth;

    public int rightWidth;

    public int topHeight;

    public int bottomHeight;

}

 

[DllImport("dwmapi.dll", PreserveSig = true)]

public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);

 

[DllImport("dwmapi.dll")]

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 };

    DwmExtendFrameIntoClientArea(helper.Handle, ref m);

}

 

image004.png
image003.jpg

Sacha Barber

unread,
Aug 3, 2010, 2:10:23 AM8/3/10
to wpf-di...@googlegroups.com
Cool
--
Sacha Barber
sacha....@gmail.com
image004.png
image003.jpg

Peter O'Hanlon

unread,
Aug 3, 2010, 3:34:16 AM8/3/10
to wpf-di...@googlegroups.com
Cools stuff there Jer.
--
Peter O'Hanlon
image004.png
image003.jpg

Daniel Vaughan

unread,
Aug 3, 2010, 6:05:56 AM8/3/10
to WPF Disciples
Cool tip Jer!


On Aug 3, 7:39 am, "Jeremiah Morrill" <jeremiah.morr...@gmail.com>
wrote:
> I'm working on a WPF application and came across something that was
> hair-pulling.  I couldn't find anything on google about it and thought to
> share so others wouldn't have to go through the pain.
>
> In this application, the main window needs custom chrome (min, max, restore
> buttons, resize borders, etc).  So I set about giving the WindowStyle a
> "None" value and the ResizeMode property to "NoResize".  Then I noticed that
> you lose the drop shadow the DWM provides!  Ok, so naturally I just wanted
> to do an AllowsTransparency = True and add my own drop shadow.but
> AllowsTransparency has such atrocious performance (sad, huh?), it wasn't an
> option for me.
>
> Took a lot guess and checking, but here's a snippet to get back your drop
> shadow on your window w/o sacrificing performance:
>
> Image without code:
>
> Image with code:
>
> [StructLayout(LayoutKind.Sequential)]
>
> public struct Margins
>
> {
>
>     public int leftWidth;
>
>     public int rightWidth;
>
>     public int topHeight;
>
>     public int bottomHeight;
>
> }
>
> [DllImport("dwmapi.dll", PreserveSig = true)]
>
> public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref
> int attrValue, int attrSize);
>
> [DllImport("dwmapi.dll")]
>
> 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 };
>
>     DwmExtendFrameIntoClientArea(helper.Handle, ref m);
>
> }
>
>
>
>  image004.png
> 1KViewDownload
>
>  image003.jpg
> 1KViewDownload

Laurent Bugnion

unread,
Aug 3, 2010, 6:26:32 AM8/3/10
to wpf-di...@googlegroups.com

This is a really cool trick. Thanks Jer

image001.jpg
image002.png

Michael Brown

unread,
Aug 3, 2010, 2:05:29 PM8/3/10
to wpf-di...@googlegroups.com

There you go again with all your interop voodoo! I’m actually surprised that WindowStyle none doesn’t support bitmap effects. Anyway keep up with the mad science!

 

--Mike

 

From: wpf-di...@googlegroups.com [mailto:wpf-di...@googlegroups.com] On Behalf Of Jeremiah Morrill
Sent: Tuesday, August 03, 2010 1:39 AM
To: wpf-di...@googlegroups.com
Subject: [WPF Disciples] OS Composed DropShadows on WPF Windows with Custom Chrome

 

I’m working on a WPF application and came across something that was hair-pulling.  I couldn’t find anything on google about it and thought to share so others wouldn’t have to go through the pain.

image001.jpg
image002.png

Sacha Barber

unread,
Aug 3, 2010, 3:22:43 PM8/3/10
to wpf-di...@googlegroups.com
J/Invoke == Jerdoo
--
Sacha Barber
sacha....@gmail.com
image002.png
image001.jpg

Lester

unread,
Aug 4, 2010, 1:39:51 AM8/4/10
to wpf-di...@googlegroups.com
image004.png
image003.jpg

Jeremiah Morrill

unread,
Aug 4, 2010, 2:37:08 AM8/4/10
to wpf-di...@googlegroups.com
You can probably use it (probably a cleaner API), though my issue was that it was not quite obvious how to get the drop shadow with my requirements on the WPF window.  Thought a bare bones snippet might save someone some stress ;)

Sent from the iPhowne
Reply all
Reply to author
Forward
0 new messages