DeleteDC() private method

private DeleteDC ( IntPtr hdc ) : bool
hdc System.IntPtr
return bool
Ejemplo n.º 1
0
        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();
        }