Example #1
0
 /// <summary>Returns the value of the specified font property for the current visual style element.</summary>
 /// <param name="rnd">The <see cref="VisualStyleRenderer"/> instance.</param>
 /// <param name="dc">The <see cref="IDeviceContext"/> used to draw the text.</param>
 /// <param name="defaultValue">A value to return if the system has no font defined for this <see cref="VisualStyleRenderer"/> instance.</param>
 /// <returns>
 /// A <see cref="Font"/> that contains the value of the property specified by the prop parameter for the current visual style element.
 /// </returns>
 public static Font GetFont2(this VisualStyleRenderer rnd, IDeviceContext dc = null, Font defaultValue = null)
 {
     using (var hdc = new SafeTempHDC(dc))
     {
         return(0 != GetThemeFont(new SafeHTHEME(rnd.Handle, false), hdc, rnd.Part, rnd.State, 210, out var f)
                                 ? defaultValue : Font.FromLogFont(f));
     }
 }
 /// <summary>Retrieves the value of a <c>MARGINS</c> property.</summary>
 /// <param name="rnd">The visual style to query.</param>
 /// <param name="dc">A device context for any font selection. This value can be <see langword="null"/>.</param>
 /// <param name="prop">The property to retrieve.</param>
 /// <returns>The margins defined for the property.</returns>
 public static Padding GetMargins2(this VisualStyleRenderer rnd, IDeviceContext dc = null, MarginProperty prop = MarginProperty.ContentMargins)
 {
     using (var hdc = new SafeTempHDC(dc))
     {
         GetThemeMargins(rnd.GetSafeHandle(), hdc, rnd.Part, rnd.State, (int)prop, null, out MARGINS m);
         return(new Padding(m.cxLeftWidth, m.cyTopHeight, m.cxRightWidth, m.cyBottomHeight));
     }
 }
Example #3
0
        /// <summary>Draws text in the specified bounding rectangle with the option of applying other text formatting.</summary>
        /// <param name="rnd">The <see cref="VisualStyleRenderer"/> instance.</param>
        /// <param name="dc">The <see cref="IDeviceContext"/> used to draw the text.</param>
        /// <param name="bounds">A <see cref="System.Drawing.Rectangle"/> in which the text is drawn.</param>
        /// <param name="text">The text to draw.</param>
        /// <param name="flags">A bitwise combination of the <see cref="TextFormatFlags"/> values.</param>
        /// <param name="options">The <see cref="DTTOPTS"/> .</param>
        public static void DrawText(this VisualStyleRenderer rnd, IDeviceContext dc, ref Rectangle bounds, string text, TextFormatFlags flags, ref DTTOPTS options)
        {
            var rc = new RECT(bounds);
            var ht = new SafeHTHEME(rnd.Handle, false);

            using (var hdc = new SafeTempHDC(dc))
                DrawThemeTextEx(ht, hdc, rnd.Part, rnd.State, text, text.Length, FromTFF(flags), ref rc, options);
            bounds = rc;
        }
Example #4
0
 /// <summary>Draws the image indicated by the given index on the specified <see cref="Graphics"/> at the specified location.</summary>
 /// <param name="imageList">The image list.</param>
 /// <param name="g">The <see cref="Graphics"/> to draw on.</param>
 /// <param name="bounds">The bounds in which to draw the image. Set width and height to 0 to draw image at full size.</param>
 /// <param name="index">The index of the image in the ImageList to draw.</param>
 /// <param name="bgColor">
 /// The background color of the image. This parameter can be a <see cref="Color"/> value or <see cref="COLORREF.None"/> so the image is drawn
 /// transparently or <see cref="COLORREF.Default"/> so the image is drawn using the background color of the image list.
 /// </param>
 /// <param name="fgColor">
 /// The foreground color of the image. This parameter can be a <see cref="Color"/> value or <see cref="COLORREF.None"/> so the image is blended
 /// with the color of the destination device context or <see cref="COLORREF.Default"/> so the image is drawn using the system highlight color
 /// as the foreground color.
 /// </param>
 /// <param name="style">The drawing style.</param>
 /// <param name="overlayImageIndex">Optional index of an overlay image.</param>
 /// <exception cref="System.ComponentModel.Win32Exception">Unable to draw the image with defined parameters.</exception>
 public static void Draw(this ImageList imageList, Graphics g, Rectangle bounds, int index, COLORREF bgColor, COLORREF fgColor, IMAGELISTDRAWFLAGS style = IMAGELISTDRAWFLAGS.ILD_NORMAL, int overlayImageIndex = 0)
 {
     if (index < 0 || index >= imageList.Images.Count)
     {
         throw new ArgumentOutOfRangeException(nameof(index));
     }
     if (overlayImageIndex < 0 || overlayImageIndex > imageList.GetOverlayCount())
     {
         throw new ArgumentOutOfRangeException(nameof(overlayImageIndex));
     }
     using (var hg = new SafeTempHDC(g))
     {
         var p = new IMAGELISTDRAWPARAMS(hg, bounds, index, bgColor, style | (IMAGELISTDRAWFLAGS)INDEXTOOVERLAYMASK(overlayImageIndex))
         {
             rgbFg = fgColor
         };
         imageList.GetIImageList().Draw(p);
     }
 }
Example #5
0
        /// <summary>
        /// Gets the background image of the current visual style element within the specified background color. If <paramref name="states"/>
        /// is set, the resulting image will contain each of the state images side by side.
        /// </summary>
        /// <param name="rnd">The <see cref="VisualStyleRenderer"/> instance.</param>
        /// <param name="clr">The background color. This color cannot have an alpha channel.</param>
        /// <param name="states">The optional list of states to render side by side.</param>
        /// <returns>The background image.</returns>
        public static Bitmap GetBackgroundBitmap(this VisualStyleRenderer rnd, Color clr, int[] states = null)
        {
            const int wh = 200;

            if (rnd == null)
            {
                throw new ArgumentNullException(nameof(rnd));
            }
            rnd.SetParameters(rnd.Class, rnd.Part, 0);
            if (states == null || states.Length == 0)
            {
                states = new[] { rnd.State }
            }
            ;
            var i = states.Length;

            // Get image size
            Size imgSz;

            using (var sg = Graphics.FromHwnd(IntPtr.Zero))
                imgSz = rnd.GetPartSize(sg, new Rectangle(0, 0, wh, wh), ThemeSizeType.Draw);
            if (imgSz.Width == 0 || imgSz.Height == 0)
            {
                imgSz = new Size(rnd.GetInteger(IntegerProperty.Width), rnd.GetInteger(IntegerProperty.Height));
            }
            if (imgSz.Width == 0 || imgSz.Height == 0)
            {
                using (var sg = Graphics.FromHwnd(IntPtr.Zero))
                    imgSz = MaxSize(rnd.GetPartSize(sg, new Rectangle(0, 0, wh, wh), ThemeSizeType.Minimum), imgSz);
            }

            var bounds = new Rectangle(0, 0, imgSz.Width * i, imgSz.Height);

            // Draw each background linearly down the bitmap
            using (var memoryHdc = SafeHDC.ScreenCompatibleDCHandle)
            {
                // Create a device-independent bitmap and select it into our DC
                var info = new BITMAPINFO(bounds.Width, -bounds.Height);
                using (memoryHdc.SelectObject(CreateDIBSection(HDC.NULL, info, DIBColorMode.DIB_RGB_COLORS, out var ppv)))
                {
                    using (var memoryGraphics = Graphics.FromHdc(memoryHdc.DangerousGetHandle()))
                    {
                        // Setup graphics
                        memoryGraphics.CompositingMode    = CompositingMode.SourceOver;
                        memoryGraphics.CompositingQuality = CompositingQuality.HighQuality;
                        memoryGraphics.SmoothingMode      = SmoothingMode.HighQuality;
                        memoryGraphics.Clear(clr);

                        // Draw each background linearly down the bitmap
                        var rect = new Rectangle(0, 0, imgSz.Width, imgSz.Height);
                        foreach (var state in states)
                        {
                            rnd.SetParameters(rnd.Class, rnd.Part, state);
                            rnd.DrawBackground(memoryGraphics, rect);
                            rect.X += imgSz.Width;
                        }
                    }

                    // Copy DIB to Bitmap
                    var bmp = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
                    using (var primaryHdc = new SafeTempHDC(Graphics.FromImage(bmp)))
                        BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, RasterOperationMode.SRCCOPY);
                    return(bmp);
                }
            }
        }
Example #6
0
        /// <summary>Performs a buffered animation operation. The animation consists of a cross-fade between the contents of two buffers over a specified period of time.</summary>
        /// <typeparam name="TState">The type of the state that is used to determine the image to paint.</typeparam>
        /// <typeparam name="TParam">The type of the parameter that is passed into this method.</typeparam>
        /// <param name="graphics">The target DC on which the buffer is animated.</param>
        /// <param name="ctrl">The window in which the animations play.</param>
        /// <param name="bounds">Specifies the area of the target DC in which to draw.</param>
        /// <param name="paintAction">A method delegate that performs the painting of the control at a given state.</param>
        /// <param name="currentState">The current state to use to start drawing the animation.</param>
        /// <param name="newState">The final state to use to finish drawing the animation.</param>
        /// <param name="getDuration">A method delegate that gets the duration of the animation, in milliseconds.</param>
        /// <param name="data">User-defined data to pass to the <paramref name="paintAction"/> callback.</param>
        public static void PaintAnimation <TState, TParam>(Graphics graphics, IWin32Window ctrl, Rectangle bounds,
                                                           PaintAction <TState, TParam> paintAction, TState currentState, TState newState, GetDuration <TState> getDuration, TParam data)
        {
            try
            {
                if (System.Environment.OSVersion.Version.Major >= 6)
                {
                    // If this handle is running with a different state, stop the animations
                    if (paintAnimationInstances.TryGetValue(ctrl.Handle, out var val))
                    {
                        if (!Equals(val.Item1, currentState) || !Equals(val.Item2, newState))
                        {
                            BufferedPaintStopAllAnimations(ctrl.Handle);
                            System.Diagnostics.Debug.WriteLine("BufferedPaintStop.");
                            paintAnimationInstances[ctrl.Handle] = new Tuple <object, object>(currentState, newState);
                        }
                    }
                    else
                    {
                        paintAnimationInstances.Add(ctrl.Handle, new Tuple <object, object>(currentState, newState));
                    }

                    using (var hdc = new SafeTempHDC(graphics))
                    {
                        if (hdc.IsNull)
                        {
                            return;
                        }
                        // see if this paint was generated by a soft-fade animation
                        if (BufferedPaintRenderAnimation(ctrl.Handle, hdc))
                        {
                            paintAnimationInstances.Remove(ctrl.Handle);
                            return;
                        }

                        var animParams = new BP_ANIMATIONPARAMS(BP_ANIMATIONSTYLE.BPAS_LINEAR, getDuration?.Invoke(currentState, newState) ?? 0);
                        using (var h = new BufferedAnimationPainter(ctrl, hdc, bounds, animParams, BP_PAINTPARAMS.NoClip))
                        {
                            if (!h.IsInvalid)
                            {
                                if (h.SourceGraphics != null)
                                {
                                    paintAction(h.SourceGraphics, bounds, currentState, data);
                                }
                                if (h.DestinationGraphics != null)
                                {
                                    paintAction(h.DestinationGraphics, bounds, newState, data);
                                }
                            }
                            else
                            {
                                // hdc.Dispose();
                                paintAction(graphics, bounds, newState, data);
                            }
                        }
                    }
                }
                else
                {
                    paintAction(graphics, bounds, newState, data);
                }
            }
            catch { }
            System.Diagnostics.Debug.WriteLine($"BufferedPaint state items = {paintAnimationInstances.Count}.");
        }
Example #7
0
 /// <summary>Performs a buffered paint operation.</summary>
 /// <typeparam name="TState">The type of the state that is used to determine the image to paint.</typeparam>
 /// <typeparam name="TParam">The type of the parameter that is passed into this method.</typeparam>
 /// <param name="graphics">The target DC on which the buffer is painted.</param>
 /// <param name="bounds">Specifies the area of the target DC in which to draw.</param>
 /// <param name="paintAction">A method delegate that performs the painting of the control at the provided state.</param>
 /// <param name="currentState">The current state to use to start drawing the animation.</param>
 /// <param name="data">User-defined data to pass to the <paramref name="paintAction"/> callback.</param>
 public static void Paint <TState, TParam>(Graphics graphics, Rectangle bounds, PaintAction <TState, TParam> paintAction, TState currentState, TParam data)
 {
     using (var g = new SafeTempHDC(graphics))
         using (var bp = new BufferedPainter(g, bounds))
             paintAction(bp.Graphics, bounds, currentState, data);
 }
Example #8
0
 /// <summary>
 /// Provides the size, in pixels, of the specified text when drawn with the specified font and formatting instructions, using the
 /// specified size to create the initial bounding rectangle for the text.
 /// </summary>
 /// <param name="dc">The device context object.</param>
 /// <param name="text">The text to measure.</param>
 /// <param name="font">The <see cref="Font"/> to apply to the measured text.</param>
 /// <param name="proposedSize">The <see cref="Size"/> of the initial bounding rectangle.</param>
 /// <param name="flags">The formatting instructions to apply to the measured text.</param>
 /// <returns>
 /// The return value is the text height in logical units. If <see cref="TextFormatFlags.VerticalCenter"/> or <see
 /// cref="TextFormatFlags.Bottom"/> is specified, the return value is the offset to the bottom of the drawn text.
 /// </returns>
 public static int MeasureText(this IDeviceContext dc, System.Text.StringBuilder text, Font font, Size proposedSize, TextFormatFlags flags)
 {
     using var hdc = new SafeTempHDC(dc);
     using var ctx = new GdiObjectContext(hdc, (HFONT)font.ToHfont());
     return(Win32Error.ThrowLastErrorIf(DrawTextEx(hdc, text, text.Length, new RECT(0, 0, proposedSize.Width, proposedSize.Height), (DrawTextFlags)(int)flags | DrawTextFlags.DT_CALCRECT), h => h == 0));
 }