private void ExtendFrameIntoClientArea() { if (!OsUtils.CompositionEnabled()) { return; } Marshal.ThrowExceptionForHR(NativeMethods.DwmExtendFrameIntoClientArea(this.Handle, ref this.glassMargins)); }
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e) { if (OsUtils.WinVistaOrLater() && VisualStyleRenderer.IsSupported) { if (!OsUtils.CompositionEnabled()) { e.Graphics.DrawLine(this.nonAeroBorder, 0, e.AffectedBounds.Bottom - 1, e.ToolStrip.Width, e.AffectedBounds.Bottom - 1); } } else { e.Graphics.DrawLine(this.tabBorder, 0, e.AffectedBounds.Bottom - 1, e.ToolStrip.Width, e.AffectedBounds.Bottom - 1); } ToolStripButton @checked = null; // Find the currently checked ToolStripButton foreach (ToolStripItem item in e.ToolStrip.Items) { ToolStripButton buttonItem = item as ToolStripButton; if (buttonItem != null && buttonItem.Checked) { @checked = buttonItem; break; } } if (@checked != null) { // Extend the bottom of the tab over the client area border, joining the tab onto the main client area using (SolidBrush toolbarBkg = new SolidBrush(this.GetActiveTabBtmCol(e.ToolStrip, @checked))) { e.Graphics.FillRectangle(toolbarBkg, new Rectangle(@checked.Bounds.Left, @checked.Bounds.Bottom, @checked.Bounds.Width - TabSeparation, e.ToolStrip.Bounds.Bottom - @checked.Bounds.Bottom)); } e.Graphics.DrawLine(this.tabBorder, @checked.Bounds.Left, @checked.Bounds.Bottom, @checked.Bounds.Left, e.AffectedBounds.Bottom); e.Graphics.DrawLine(this.tabBorder, @checked.Bounds.Right - TabSeparation, @checked.Bounds.Bottom, @checked.Bounds.Right - TabSeparation, e.AffectedBounds.Bottom); } }
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e) { if (OsUtils.CompositionEnabled()) { // Set the background colour to transparent to make it glass e.Graphics.Clear(Color.Transparent); } else { if (VisualStyleRenderer.IsSupported && OsUtils.WinVistaOrLater()) { // Set the background the same as the title bar to give the illusion of an extended frame if (this.isActive) { // It would be simpler to use e.Graphics.Clear(SystemColors.GradientActiveCaption), but // that crashes sometimes when running under terminal services due to a bug in GDI+ using (Brush backgroundBrush = new SolidBrush(SystemColors.GradientActiveCaption)) { e.Graphics.FillRectangle(backgroundBrush, e.AffectedBounds); } } else { // It would be simpler to use e.Graphics.Clear(SystemColors.GradientInactiveCaption), but // that crashes sometimes when running under terminal services due to a bug in GDI+ using (Brush backgroundBrush = new SolidBrush(SystemColors.GradientInactiveCaption)) { e.Graphics.FillRectangle(backgroundBrush, e.AffectedBounds); } } } else { base.OnRenderToolStripBackground(e); } } }
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) { if (!OsUtils.CompositionEnabled()) { // The OS doesn't support desktop composition, or it isn't enabled base.OnRenderItemText(e); return; } // Drawing text on glass is a bit of a pain - text generated with GDI (e.g. standard // controls) ends up being transparent as GDI doesn't understand alpha transparency. // GDI+ is fine drawing text on glass but it doesn't use ClearType, so the text ends // up looking out of place, ugly or both. The proper way is using DrawThemeTextEx, // which works fine, but requires a top-down DIB to draw to, rather than the bottom // up ones that GDI normally uses. Hence; create top-down DIB, draw text to it and // then AlphaBlend it in to the graphics object that we are rendering to. // Get the rendering HDC, and create a compatible one for drawing the text to IntPtr renderHdc = e.Graphics.GetHdc(); IntPtr memoryHdc = NativeMethods.CreateCompatibleDC(renderHdc); // NULL Pointer if (memoryHdc == IntPtr.Zero) { throw new Win32Exception(); } NativeMethods.BITMAPINFO info = default(NativeMethods.BITMAPINFO); info.biSize = Convert.ToUInt32(Marshal.SizeOf(typeof(NativeMethods.BITMAPINFO))); info.biWidth = e.TextRectangle.Width; info.biHeight = -e.TextRectangle.Height; // Negative = top-down info.biPlanes = 1; info.biBitCount = 32; info.biCompression = NativeMethods.BI_RGB; IntPtr bits = IntPtr.Zero; // Create the top-down DIB IntPtr dib = NativeMethods.CreateDIBSection(renderHdc, ref info, 0, ref bits, IntPtr.Zero, 0); // NULL Pointer if (dib == IntPtr.Zero) { throw new Win32Exception(); } // Select the created DIB into our memory DC for use // NULL Pointer if (NativeMethods.SelectObject(memoryHdc, dib) == IntPtr.Zero) { throw new Win32Exception(); } // Create a font we can use with GetThemeTextEx IntPtr hFont = e.TextFont.ToHfont(); // And select it into the DC as well // NULL Pointer if (NativeMethods.SelectObject(memoryHdc, hFont) == IntPtr.Zero) { throw new Win32Exception(); } // Fetch a VisualStyleRenderer suitable for toolbar text VisualStyleRenderer renderer = new VisualStyleRenderer(VisualStyleElement.ToolBar.Button.Normal); // Set up a RECT for the area to draw the text in NativeMethods.RECT textRect = default(NativeMethods.RECT); textRect.left = 0; textRect.top = 0; textRect.right = e.TextRectangle.Width; textRect.bottom = e.TextRectangle.Height; // Options for GetThemeTextEx NativeMethods.DTTOPTS opts = default(NativeMethods.DTTOPTS); opts.dwSize = Convert.ToUInt32(Marshal.SizeOf(opts)); opts.dwFlags = NativeMethods.DTT_COMPOSITED | NativeMethods.DTT_TEXTCOLOR; opts.crText = Convert.ToUInt32(ColorTranslator.ToWin32(e.TextColor)); // Alpha blended text of the colour specified // Paint the text Marshal.ThrowExceptionForHR(NativeMethods.DrawThemeTextEx(renderer.Handle, memoryHdc, 0, 0, e.Text, -1, (uint)e.TextFormat, ref textRect, ref opts)); // Set up the AlphaBlend copy NativeMethods.BLENDFUNCTION blendFunc = default(NativeMethods.BLENDFUNCTION); blendFunc.BlendOp = NativeMethods.AC_SRC_OVER; blendFunc.SourceConstantAlpha = 255; blendFunc.AlphaFormat = NativeMethods.AC_SRC_ALPHA; // Per-pixel alpha only // Blend the painted text into the render DC if (!NativeMethods.AlphaBlend(renderHdc, e.TextRectangle.Left, e.TextRectangle.Top, e.TextRectangle.Width, e.TextRectangle.Height, memoryHdc, 0, 0, e.TextRectangle.Width, e.TextRectangle.Height, blendFunc)) { throw new Win32Exception(); } // Clean up the GDI objects if (!NativeMethods.DeleteObject(hFont)) { throw new Win32Exception(); } if (!NativeMethods.DeleteObject(dib)) { throw new Win32Exception(); } if (!NativeMethods.DeleteDC(memoryHdc)) { throw new Win32Exception(); } e.Graphics.ReleaseHdc(); }