/// <summary> /// Draws composited text onto the glass area of a form. /// </summary> /// <param name="dc">The <see cref="IDeviceContext"/> onto which the composited text should be drawn.</param> /// <param name="text">The text to draw.</param> /// <param name="font">The <see cref="Font"/> to apply to the drawn text.</param> /// <param name="bounds">The <see cref="Rectangle" /> that represents the bounds of the text.</param> /// <param name="padding">The <see cref="Padding"/> around the text; necessary to allow space for the glow effect.</param> /// <param name="foreColor">The <see cref="Color" /> to apply to the drawn text.</param> /// <param name="textFormat">A bitwise combination of the <see cref="TextFormatFlags" /> values.</param> /// <param name="glowSize">Specifies the size of a glow that will be drawn on the background prior to any text being drawn.</param> /// <remarks> /// <para> /// Do not use this method to draw text on non-glass areas of a form. /// </para> /// </remarks> /// <exception cref="NotSupportedException">The current operating system does not support glass, or the Desktop Window Manager is not enabled.</exception> /// <exception cref="ArgumentNullException"><paramref name="dc"/>, <paramref name="text"/> or <paramref name="font"/> is <see langword="null"/>.</exception> public static void DrawCompositedText(IDeviceContext dc, string text, Font font, Rectangle bounds, Padding padding, Color foreColor, int glowSize, TextFormatFlags textFormat) { if (!IsDwmCompositionEnabled) { throw new NotSupportedException(Properties.Resources.GlassNotSupportedError); } if (dc == null) { throw new ArgumentNullException("dc"); } if (text == null) { throw new ArgumentNullException("text"); } if (font == null) { throw new ArgumentNullException("font"); } IntPtr primaryHdc = dc.GetHdc(); try { using (SafeDeviceHandle memoryHdc = NativeMethods.CreateCompatibleDC(primaryHdc)) using (SafeGDIHandle fontHandle = new SafeGDIHandle(font.ToHfont(), true)) using (SafeGDIHandle dib = NativeMethods.CreateDib(bounds, primaryHdc, memoryHdc)) { NativeMethods.SelectObject(memoryHdc, fontHandle); // Draw glowing text 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 = Marshal.SizeOf(typeof(NativeMethods.DTTOPTS)); dttOpts.dwFlags = NativeMethods.DrawThemeTextFlags.Composited | NativeMethods.DrawThemeTextFlags.GlowSize | NativeMethods.DrawThemeTextFlags.TextColor; dttOpts.crText = ColorTranslator.ToWin32(foreColor); dttOpts.iGlowSize = glowSize; NativeMethods.RECT textBounds = new NativeMethods.RECT(padding.Left, padding.Top, bounds.Width - padding.Right, bounds.Height - padding.Bottom); NativeMethods.DrawThemeTextEx(renderer.Handle, memoryHdc, 0, 0, text, text.Length, (int)textFormat, ref textBounds, ref dttOpts); // Copy to foreground const int SRCCOPY = 0x00CC0020; NativeMethods.BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY); } } finally { dc.ReleaseHdc(); } }
/// <summary> /// Draws composited text onto the glass area of a form. /// </summary> /// <param name="dc">The <see cref="IDeviceContext"/> onto which the composited text should be drawn.</param> /// <param name="text">The text to draw.</param> /// <param name="font">The <see cref="Font"/> to apply to the drawn text.</param> /// <param name="bounds">The <see cref="Rectangle" /> that represents the bounds of the text.</param> /// <param name="padding">The <see cref="Padding"/> around the text; necessary to allow space for the glow effect.</param> /// <param name="foreColor">The <see cref="Color" /> to apply to the drawn text.</param> /// <param name="textFormat">A bitwise combination of the <see cref="TextFormatFlags" /> values.</param> /// <param name="glowSize">Specifies the size of a glow that will be drawn on the background prior to any text being drawn.</param> /// <remarks> /// <para> /// Do not use this method to draw text on non-glass areas of a form. /// </para> /// </remarks> /// <exception cref="NotSupportedException">The current operating system does not support glass, or the Desktop Window Manager is not enabled.</exception> /// <exception cref="ArgumentNullException"><paramref name="dc"/>, <paramref name="text"/> or <paramref name="font"/> is <see langword="null"/>.</exception> public static void DrawCompositedText(IDeviceContext dc, string text, Font font, Rectangle bounds, Padding padding, Color foreColor, int glowSize, TextFormatFlags textFormat) { if( !IsDwmCompositionEnabled ) throw new NotSupportedException(Properties.Resources.GlassNotSupportedError); if( dc == null ) throw new ArgumentNullException("dc"); if( text == null ) throw new ArgumentNullException("text"); if( font == null ) throw new ArgumentNullException("font"); IntPtr primaryHdc = dc.GetHdc(); try { using( SafeDeviceHandle memoryHdc = NativeMethods.CreateCompatibleDC(primaryHdc) ) using( SafeGDIHandle fontHandle = new SafeGDIHandle(font.ToHfont(), true) ) using( SafeGDIHandle dib = NativeMethods.CreateDib(bounds, primaryHdc, memoryHdc) ) { NativeMethods.SelectObject(memoryHdc, fontHandle); // Draw glowing text 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 = Marshal.SizeOf(typeof(NativeMethods.DTTOPTS)); dttOpts.dwFlags = NativeMethods.DrawThemeTextFlags.Composited | NativeMethods.DrawThemeTextFlags.GlowSize | NativeMethods.DrawThemeTextFlags.TextColor; dttOpts.crText = ColorTranslator.ToWin32(foreColor); dttOpts.iGlowSize = glowSize; NativeMethods.RECT textBounds = new NativeMethods.RECT(padding.Left, padding.Top, bounds.Width - padding.Right, bounds.Height - padding.Bottom); NativeMethods.DrawThemeTextEx(renderer.Handle, memoryHdc, 0, 0, text, text.Length, (int)textFormat, ref textBounds, ref dttOpts); // Copy to foreground const int SRCCOPY = 0x00CC0020; NativeMethods.BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY); } } finally { dc.ReleaseHdc(); } }