public static void DrawTextOnGlass(Graphics graphics, string text, Font font, Rectangle bounds, Color color, TextFormatFlags flags, bool withGlow) { IntPtr primaryHdc = graphics.GetHdc(); // Memory DC for off screen rendering. IntPtr memoryHdc = CreateCompatibleDC(primaryHdc); BITMAPINFO info = new BITMAPINFO(); info.biSize = Marshal.SizeOf(info); info.biWidth = bounds.Width; info.biHeight = -bounds.Height; info.biPlanes = 1; info.biBitCount = 32; info.biCompression = 0; // BI_RGB IntPtr dib = CreateDIBSection(primaryHdc, info, 0, 0, IntPtr.Zero, 0); SelectObject(memoryHdc, dib); IntPtr fontHandle = font.ToHfont(); SelectObject(memoryHdc, fontHandle); // Draw glowing text if enabled. VisualStyleRenderer renderer = new VisualStyleRenderer(VisualStyleElement.Window.Caption.Active); DTTOPTS dttOpts = new DTTOPTS(); dttOpts.dwSize = (uint)Marshal.SizeOf(typeof(DTTOPTS)); if (withGlow) { dttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE | DTT_TEXTCOLOR; dttOpts.iGlowSize = 12; } else { dttOpts.dwFlags = DTT_COMPOSITED | DTT_TEXTCOLOR; dttOpts.iGlowSize = 0; } dttOpts.crText = (uint)ColorTranslator.ToWin32(color); RECT textBounds = new RECT(dttOpts.iGlowSize, 0, bounds.Width - dttOpts.iGlowSize, bounds.Height); DrawThemeTextEx(renderer.Handle, memoryHdc, 0, 0, text, -1, (int)flags, ref textBounds, ref dttOpts); //const int SRCCOPY = 0x00CC0020; //BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY); BLENDFUNCTION blend = new Win32.BLENDFUNCTION(AC_SRC_OVER, 0, 255, AC_SRC_ALPHA); AlphaBlend(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, bounds.Width, bounds.Height, blend); // Clean up DeleteObject(fontHandle); DeleteObject(dib); DeleteDC(memoryHdc); graphics.ReleaseHdc(primaryHdc); }
/// <summary> /// Sets the given bitmap as window content with transparent parts via the /// layered windows API. /// </summary> /// <param name="bitmap">The bitmap to set.</param> /// <param name="opacity">The overall opacity (255 = opaque).</param> public static void SetBitmap(Control control, Bitmap bitmap, int opacity) { if (bitmap.PixelFormat != PixelFormat.Format32bppArgb) throw new ApplicationException("The bitmap must be 32ppp with alpha-channel."); IntPtr screenDc = Win32.GetDC(IntPtr.Zero); IntPtr memDc = Win32.CreateCompatibleDC(screenDc); IntPtr hBitmap = IntPtr.Zero; IntPtr oldBitmap = IntPtr.Zero; try { hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); // grab a GDI handle from this GDI+ bitmap oldBitmap = Win32.SelectObject(memDc, hBitmap); Win32.SIZE size = new Win32.SIZE(bitmap.Width, bitmap.Height); Win32.POINT pointSource = new Win32.POINT(0, 0); Win32.POINT topPos = new Win32.POINT(control.Left, control.Top); Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION(); blend.BlendOp = Win32.AC_SRC_OVER; blend.BlendFlags = 0; blend.SourceConstantAlpha = (byte)opacity; blend.AlphaFormat = Win32.AC_SRC_ALPHA; if (!control.IsDisposed && !control.Disposing) { Win32.UpdateLayeredWindow(control.Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, Win32.ULW_ALPHA); } } finally { Win32.ReleaseDC(IntPtr.Zero, screenDc); if (hBitmap != IntPtr.Zero) { Win32.SelectObject(memDc, oldBitmap); Win32.DeleteObject(hBitmap); } Win32.DeleteDC(memDc); } }