Note that there are some explanatory texts on larger screens.

plurals
  1. PORe-drawing the Window title when using custom chrome and DWM
    text
    copied!<p>I am using the WPF Shell Integration Library (<a href="http://archive.msdn.microsoft.com/WPFShell" rel="nofollow">http://archive.msdn.microsoft.com/WPFShell</a>) however when I use the custom chrome with Aero the title bar is removed.</p> <p>I understand that I need to use DrawThemeTextEx function to re-draw the window title, however I can not find any C# samples that do this. I have located a guide at <a href="http://msdn.microsoft.com/en-us/library/bb688195%28v=vs.85%29.aspx" rel="nofollow">Custom Window Frame using DWM (Windows)</a> that details the painting the caption title.</p> <p>I am not really sure (I have little experience with pinvoke) how to do this in C# so that the correct system fonts are used etc. Is someone able to provide a C# sample that I could integrate into the WPF Shell Integration Library?</p> <p><strong>Update #1:</strong> I have tried this code within a Windows Form project and it works fine. I notice that the Windows Form will loose the title text if I move the form off the screen. So I believe the issue maybe related to this. I have tried drawing the title text within the OnRender event however that doesn't fix the issue.</p> <p>I have added the following code to the WindowChromeWorker.cs:</p> <pre><code> private void _DrawCustomTitle(IntPtr hwnd) { if (NativeMethods.DwmIsCompositionEnabled()) { Standard.RECT rcClient = new Standard.RECT(); NativeMethods.GetClientRect(hwnd, ref rcClient); Standard.RECT rcPaint = rcClient; rcPaint.Top += 8; rcPaint.Right -= 125; rcPaint.Left += 8; rcPaint.Bottom = 50; IntPtr destdc = NativeMethods.GetDC(hwnd); IntPtr Memdc = NativeMethods.CreateCompatibleDC(destdc); // Set up a memory DC where we'll draw the text. IntPtr bitmap; IntPtr bitmapOld = IntPtr.Zero; IntPtr logFont; uint uFormat = NativeMethods.DT_SINGLELINE | NativeMethods.DT_TOP | NativeMethods.DT_LEFT | NativeMethods.DT_WORD_ELLIPSIS; BITMAPINFO dib = new BITMAPINFO(); dib.bmiHeader.biHeight = -(rcClient.Bottom - rcClient.Top); // negative because DrawThemeTextEx() uses a top-down DIB dib.bmiHeader.biWidth = rcClient.Right - rcClient.Left; dib.bmiHeader.biPlanes = 1; dib.bmiHeader.biSize = Marshal.SizeOf(typeof(BITMAPINFOHEADER)); dib.bmiHeader.biBitCount = 32; dib.bmiHeader.biCompression = NativeMethods.BI_RGB; if (!(NativeMethods.SaveDC(Memdc) == 0)) { bitmap = NativeMethods.CreateDIBSection(Memdc, ref dib, NativeMethods.DIB_RGB_COLORS, 0, IntPtr.Zero, 0); // Create a 32-bit bmp for use in offscreen drawing when glass is on if (!(bitmap == IntPtr.Zero)) { bitmapOld = NativeMethods.SelectObject(Memdc, bitmap); System.Drawing.Font font = new System.Drawing.Font("Segoe UI", 9f); IntPtr hFont = font.ToHfont(); logFont = NativeMethods.SelectObject(Memdc, hFont); try { System.Windows.Forms.VisualStyles.VisualStyleRenderer renderer = new System.Windows.Forms.VisualStyles.VisualStyleRenderer(System.Windows.Forms.VisualStyles.VisualStyleElement.Window.Caption.Active); NativeMethods.DTTOPTS dttOpts = new NativeMethods.DTTOPTS(); dttOpts.dwSize = (int)Marshal.SizeOf(typeof(NativeMethods.DTTOPTS)); dttOpts.dwFlags = NativeMethods.DTT_COMPOSITED | NativeMethods.DTT_GLOWSIZE; dttOpts.iGlowSize = 15; string title = "Windows Title"; NativeMethods.DrawThemeTextEx(renderer.Handle, Memdc, 0, 0, title, -1, uFormat, ref rcPaint, ref dttOpts); NativeMethods.BitBlt(destdc, rcClient.Left, rcClient.Top, rcClient.Right - rcClient.Left, rcClient.Bottom - rcClient.Top, Memdc, 0, 0, NativeMethods.SRCCOPY); } catch (Exception e) { System.Diagnostics.Debug.WriteLine(e.Message); } // Clean Up NativeMethods.SelectObject(Memdc, bitmapOld); NativeMethods.SelectObject(Memdc, logFont); NativeMethods.DeleteObject(bitmap); NativeMethods.DeleteObject(hFont); NativeMethods.ReleaseDC(Memdc, -1); NativeMethods.DeleteDC(Memdc); } } } } </code></pre> <p>I am then calling the DrawCustomTitle within the following function after the DWM glass is extended. Any idea why this would not be working.</p> <pre><code> private void _ExtendGlassFrame() { Assert.IsNotNull(_window); // Expect that this might be called on OSes other than Vista. if (!Utility.IsOSVistaOrNewer) { // Not an error. Just not on Vista so we're not going to get glass. return; } if (IntPtr.Zero == _hwnd) { // Can't do anything with this call until the Window has been shown. return; } // Ensure standard HWND background painting when DWM isn't enabled. if (!NativeMethods.DwmIsCompositionEnabled()) { _hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; } else { // This makes the glass visible at a Win32 level so long as nothing else is covering it. // The Window's Background needs to be changed independent of this. // Apply the transparent background to the HWND _hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; // Thickness is going to be DIPs, need to convert to system coordinates. Point deviceTopLeft = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.GlassFrameThickness.Left, _chromeInfo.GlassFrameThickness.Top)); Point deviceBottomRight = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.GlassFrameThickness.Right, _chromeInfo.GlassFrameThickness.Bottom)); var dwmMargin = new MARGINS { // err on the side of pushing in glass an extra pixel. cxLeftWidth = (int)Math.Ceiling(deviceTopLeft.X), cxRightWidth = (int)Math.Ceiling(deviceBottomRight.X), cyTopHeight = (int)Math.Ceiling(deviceTopLeft.Y), cyBottomHeight = (int)Math.Ceiling(deviceBottomRight.Y), }; NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref dwmMargin); this._DrawCustomTitle(_hwnd); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload