{"id":105,"date":"2010-12-20T01:57:20","date_gmt":"2010-12-19T14:57:20","guid":{"rendered":"http:\/\/blog.quppa.net\/2010\/12\/20\/windows-7-style-notification-area-applications-in-wpf-part-5-fixing-aero-borders\/"},"modified":"2010-12-20T01:57:20","modified_gmt":"2010-12-19T14:57:20","slug":"windows-7-style-notification-area-applications-in-wpf-part-5-fixing-aero-borders","status":"publish","type":"post","link":"https:\/\/www.quppa.net\/blog\/2010\/12\/20\/windows-7-style-notification-area-applications-in-wpf-part-5-fixing-aero-borders\/","title":{"rendered":"Windows 7-style Notification Area Applications in WPF: Part 5 (Fixing Aero Borders)"},"content":{"rendered":"<blockquote><p><a href=\"https:\/\/github.com\/Quppa\/NotificationAreaIconSampleAppWPF\" title=\"GitHub: NotificationAreaIconSampleAppWPF\">View source on GitHub.<\/a><\/p><\/blockquote>\n<p>An issue that came to my attention only recently is that the borders of <strike>WPF<\/strike> (<strong>update:<\/strong> WPF is not actually to blame) windows without captions\/title-bars (that is, with ResizeMode set to \u2018CanResize\u2019 and WindowStyle set to \u2018None\u2019) are drawn incorrectly when the DWM (read: Aero Glass) is enabled. Specifically, the upper and left borders are drawn one pixel too thin (e.g. 3 pixels when the system setting is 4 pixels) and the colour of the bottom and right borders is different to that of other windows. I\u2019ve tried to illustrate these differences in the screenshot below (the image on the left is of a WPF window).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" title=\"Border differences in WPF windows\" border=\"0\" alt=\"Aero Border Example\" src=\"https:\/\/www.quppa.net\/blog\/wp-content\/uploads\/Aero-Border.png\" width=\"367\" height=\"353\"\/><\/p>\n<p>It is conceivable that this will be fixed in a future version of <strike>WPF<\/strike> Windows, but for now we can use the <a title=\"MSDN: DwmExtendFrameIntoClientArea Function\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa969512(v=vs.85).aspx\">DwmExtendFrameIntoClientArea function<\/a> to do it manually. This is only necessary when the DWM is enabled, of course.<\/p>\n<p><!--more--><\/p>\n<p>Extending Aero Glass into the client area of a window has been covered countless times elsewhere, but I\u2019ll reproduce the process here for convenience.<\/p>\n<p>First, we\u2019ll define the PInvoke signature:<\/p>\n<pre class=\"lang:c# decode:true \">[DllImport(\"dwmapi.dll\")]\nprivate static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);<\/pre>\n<p>You\u2019ll notice that the function uses a MARGINS type, which is pretty simple:<\/p>\n<pre class=\"lang:c# decode:true \">[StructLayout(LayoutKind.Sequential)]\nprivate struct MARGINS\n{\n    public int cxLeftWidth;\n    public int cxRightWidth;\n    public int cyTopHeight;\n    public int cyBottomHeight;\n};<\/pre>\n<p>In our window\u2019s markup, we need to use a Border (or equivalent) as our root element:<\/p>\n<pre class=\"lang:xaml decode:true \">&lt;Border Name=\"WindowBorder\" Background=\"{DynamicResource {x:Static SystemColors.WindowBrushKey}}\"&gt;\n   ...\n&lt;\/Border&gt;<\/pre>\n<p>And finally, in our code behind, we\u2019ll add the following code (you can add it to your Window\u2019s Loaded event if you only want to do this once):<\/p>\n<pre class=\"lang:c# decode:true \">\/\/ work out the current screen's DPI\nMatrix screenmatrix = windowhandlesource.CompositionTarget.TransformToDevice;\ndouble dpiX = screenmatrix.M11; \/\/ 1.0 = 96 dpi\nif (GlassEnabled)\n{\n  \/\/ set the root border element's margin to 1 pixel\n  WindowBorder.Margin = new Thickness(1 \/ dpiX);\n  this.BorderThickness = new Thickness(0);\n  \/\/ set the background of the window to transparent (otherwise the inner border colour won't be visible)\n  windowhandlesource.CompositionTarget.BackgroundColor = Colors.Transparent;\n  int xmargin = 1;\n  int ymargin = 1;\n  MARGINS margins = new MARGINS() { cxLeftWidth = xmargin, cxRightWidth = xmargin, cyBottomHeight = ymargin, cyTopHeight = ymargin };\n  DwmExtendFrameIntoClientArea(windowhandlesource.Handle, ref margins);\n}\nelse\n{\n  WindowBorder.Margin = new Thickness(0); \/\/ reset the margin if the DWM is disabled\n  this.BorderThickness = new Thickness(1 \/ dpiX); \/\/ set the window's border thickness to 1 pixel\n}<\/pre>\n<p>It is assumed that the GlassEnabled boolean I reference has been set with the <a title=\"MSDN: DwmIsCompositionEnabled Function\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa969518(v=vs.85).aspx\">DwmIsCompositionEnabled function<\/a>, the implementation of which is well documented elsewhere.<\/p>\n<p>The neat trick I used to find the window\u2019s DPI comes from <a title=\"The Code Project: How to get Windows-wide DPI Scaling number within WPF\" href=\"http:\/\/www.codeproject.com\/Messages\/3128820\/Re-How-to-get-Windows-wide-DPI-Scaling-number-with.aspx\">this post<\/a> by fjparisIII.<\/p>\n<p><strong>Update 2011-06-11: <\/strong>Fixed some DPI issues.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>View source on GitHub. An issue that came to my attention only recently is that the borders of WPF (update: WPF is not actually to blame) windows without captions\/title-bars (that is, with ResizeMode set to \u2018CanResize\u2019 and WindowStyle set to \u2018None\u2019) are drawn incorrectly when the DWM (read: Aero Glass) is enabled. Specifically, the upper &hellip; <a href=\"https:\/\/www.quppa.net\/blog\/2010\/12\/20\/windows-7-style-notification-area-applications-in-wpf-part-5-fixing-aero-borders\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Windows 7-style Notification Area Applications in WPF: Part 5 (Fixing Aero Borders)&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,6],"tags":[11,12,22,24,28,47,51,72,74,87,96,146,170,185],"class_list":["post-105","post","type-post","status-publish","format-standard","hentry","category-keiki","category-programming","tag-aero","tag-aero-glass","tag-border","tag-border-padding","tag-c","tag-dllimport","tag-dwmapi","tag-interop","tag-keiki-2","tag-notification-area","tag-pinvoke","tag-taskbar","tag-win32","tag-wpf"],"_links":{"self":[{"href":"https:\/\/www.quppa.net\/blog\/wp-json\/wp\/v2\/posts\/105","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.quppa.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.quppa.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.quppa.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.quppa.net\/blog\/wp-json\/wp\/v2\/comments?post=105"}],"version-history":[{"count":0,"href":"https:\/\/www.quppa.net\/blog\/wp-json\/wp\/v2\/posts\/105\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.quppa.net\/blog\/wp-json\/wp\/v2\/media?parent=105"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.quppa.net\/blog\/wp-json\/wp\/v2\/categories?post=105"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.quppa.net\/blog\/wp-json\/wp\/v2\/tags?post=105"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}