/// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public HitTestCode HitTestBackground(IDeviceContext dc, Rectangle backgroundRectangle, IntPtr hRgn, Point pt, HitTestOptions options)
        {
            ArgumentNullException.ThrowIfNull(dc);

            using var hdc = new DeviceContextHdcScope(dc);
            RECT backgroundRect = backgroundRectangle;

            _lastHResult = HitTestThemeBackground(this, hdc, Part, State, (uint)options, ref backgroundRect, hRgn, pt, out ushort htCode);
            return((HitTestCode)htCode);
        }
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public Size GetPartSize(IDeviceContext dc, ThemeSizeType type)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            return(GetPartSize(hdc, type, IntPtr.Zero));
        }
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public void DrawText(IDeviceContext dc, Rectangle bounds, string?textToDraw, bool drawDisabled, TextFormatFlags flags)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            DrawText(hdc, bounds, textToDraw, drawDisabled, flags);
        }
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public Rectangle GetBackgroundContentRectangle(IDeviceContext dc, Rectangle bounds)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            return(GetBackgroundContentRectangle(hdc, bounds));
        }
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public Rectangle DrawEdge(IDeviceContext dc, Rectangle bounds, Edges edges, EdgeStyle style, EdgeEffects effects)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            return(DrawEdge(hdc, bounds, edges, style, effects));
        }
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public void DrawBackground(IDeviceContext dc, Rectangle bounds, Rectangle clipRectangle)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            DrawBackground(hdc, bounds, clipRectangle, IntPtr.Zero);
        }
Esempio n. 7
0
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public TextMetrics GetTextMetrics(IDeviceContext dc)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            _lastHResult  = GetThemeTextMetrics(this, hdc, Part, State, out TextMetrics tm);
            return(tm);
        }
Esempio n. 8
0
        protected void DrawCheckFlat(
            PaintEventArgs e,
            LayoutData layout,
            Color checkColor,
            Color checkBackground,
            Color checkBorder,
            ColorData colors)
        {
            Rectangle bounds = layout.CheckBounds;

            // Removed subtracting one for Width and Height. In Everett we needed to do this,
            // since we were using GDI+ to draw the border. Now that we are using GDI,
            // we should not do before drawing the border.

            if (!layout.Options.DotNetOneButtonCompat)
            {
                bounds.Width--;
                bounds.Height--;
            }

            using (var hdc = new DeviceContextHdcScope(e))
            {
                using var hpen = new Gdi32.CreatePenScope(checkBorder);
                hdc.DrawRectangle(bounds, hpen);

                // Now subtract, since the rest of the code is like Everett.
                if (layout.Options.DotNetOneButtonCompat)
                {
                    bounds.Width--;
                    bounds.Height--;
                }

                bounds.Inflate(-1, -1);
            }

            if (Control.CheckState == CheckState.Indeterminate)
            {
                bounds.Width++;
                bounds.Height++;
                DrawDitheredFill(e.Graphics, colors.ButtonFace, checkBackground, bounds);
            }
            else
            {
                using var hdc    = new DeviceContextHdcScope(e);
                using var hbrush = new Gdi32.CreateBrushScope(checkBackground);

                // Even though we are using GDI here as opposed to GDI+ in Everett, we still need to add 1.
                bounds.Width++;
                bounds.Height++;
                hdc.FillRectangle(bounds, hbrush);
            }

            DrawCheckOnly(e, layout, colors, checkColor);
        }
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public unsafe Rectangle GetTextExtent(IDeviceContext dc, Rectangle bounds, string textToDraw, TextFormatFlags flags)
        {
            ArgumentNullException.ThrowIfNull(dc);
            textToDraw.ThrowIfNullOrEmpty();

            using var hdc = new DeviceContextHdcScope(dc);
            RECT boundsRect = bounds;

            _lastHResult = GetThemeTextExtent(this, hdc, Part, State, textToDraw, textToDraw.Length, (uint)flags, &boundsRect, out RECT rect);
            return(rect);
        }
Esempio n. 10
0
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public unsafe Padding GetMargins(IDeviceContext dc, MarginProperty prop)
        {
            ArgumentNullException.ThrowIfNull(dc);

            // Valid values are 0xe11 to 0xe13
            SourceGenerated.EnumValidator.Validate(prop, nameof(prop));

            using var hdc = new DeviceContextHdcScope(dc);
            _lastHResult  = GetThemeMargins(this, hdc, Part, State, (int)prop, null, out MARGINS margins);

            return(new Padding(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight));
        }
Esempio n. 11
0
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public unsafe Size GetPartSize(IDeviceContext dc, Rectangle bounds, ThemeSizeType type)
        {
            ArgumentNullException.ThrowIfNull(dc);

            // Valid values are 0x0 to 0x2
            SourceGenerated.EnumValidator.Validate(type, nameof(type));

            using var hdc = new DeviceContextHdcScope(dc);
            RECT boundsRect = bounds;

            _lastHResult = GetThemePartSize(this, hdc, Part, State, &boundsRect, type, out Size size);
            return(size);
        }
Esempio n. 12
0
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public HitTestCode HitTestBackground(IDeviceContext dc, Rectangle backgroundRectangle, Point pt, HitTestOptions options)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            RECT backgroundRect = backgroundRectangle;

            _lastHResult = HitTestThemeBackground(this, hdc, Part, State, (uint)options, ref backgroundRect, IntPtr.Zero, pt, out ushort htCode);
            return((HitTestCode)htCode);
        }
Esempio n. 13
0
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public Rectangle GetBackgroundExtent(IDeviceContext dc, Rectangle contentBounds)
        {
            ArgumentNullException.ThrowIfNull(dc);

            if (contentBounds.Width < 0 || contentBounds.Height < 0)
            {
                return(Rectangle.Empty);
            }

            using var hdc = new DeviceContextHdcScope(dc);
            RECT contentBoundsRect = contentBounds;

            _lastHResult = GetThemeBackgroundExtent(this, hdc, Part, State, ref contentBoundsRect, out RECT extentRect);
            return(extentRect);
        }
Esempio n. 14
0
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public unsafe Rectangle GetTextExtent(IDeviceContext dc, string textToDraw, TextFormatFlags flags)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            if (string.IsNullOrEmpty(textToDraw))
            {
                throw new ArgumentNullException(nameof(textToDraw));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            _lastHResult  = GetThemeTextExtent(this, hdc, Part, State, textToDraw, textToDraw.Length, (uint)flags, null, out RECT rect);
            return(rect);
        }
Esempio n. 15
0
        /// <summary>
        ///  Given a graphics object and bounds to draw in, this method effectively asks the passed in
        ///  control's parent to draw itself in there (it sends WM_ERASEBKGND &amp; WM_PRINTCLIENT messages
        ///  to the parent).
        /// </summary>
        public void DrawParentBackground(IDeviceContext dc, Rectangle bounds, Control childControl)
        {
            ArgumentNullException.ThrowIfNull(dc);
            ArgumentNullException.ThrowIfNull(childControl);

            if (bounds.Width < 0 || bounds.Height < 0)
            {
                return;
            }

            if (childControl.IsHandleCreated)
            {
                using var hdc = new DeviceContextHdcScope(dc);
                RECT rc = bounds;
                _lastHResult = DrawThemeParentBackground(childControl, hdc, ref rc);
            }
        }
Esempio n. 16
0
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public unsafe Padding GetMargins(IDeviceContext dc, MarginProperty prop)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Valid values are 0xe11 to 0xe13
            if (!ClientUtils.IsEnumValid(prop, (int)prop, (int)MarginProperty.SizingMargins, (int)MarginProperty.CaptionMargins))
            {
                throw new InvalidEnumArgumentException(nameof(prop), (int)prop, typeof(MarginProperty));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            _lastHResult  = GetThemeMargins(this, hdc, Part, State, (int)prop, null, out MARGINS margins);

            return(new Padding(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight));
        }
Esempio n. 17
0
        protected override void OnPaint(PaintEventArgs pevent)
        {
            base.OnPaint(pevent);

            if (Application.RenderWithVisualStyles & _useComboBoxTheme)
            {
                ComboBoxState state = ComboBoxState.Normal;

                if (MouseIsDown)
                {
                    state = ComboBoxState.Pressed;
                }
                else if (MouseIsOver)
                {
                    state = ComboBoxState.Hot;
                }

                Rectangle dropDownButtonRect = new Rectangle(0, 0, Width, Height);
                if (state == ComboBoxState.Normal)
                {
                    pevent.Graphics.FillRectangle(SystemBrushes.Window, dropDownButtonRect);
                }

                using (var hdc = new DeviceContextHdcScope(pevent))
                {
                    ComboBoxRenderer.DrawDropDownButtonForHandle(
                        hdc,
                        dropDownButtonRect,
                        state,
                        DpiHelper.IsScalingRequirementMet ? HandleInternal : IntPtr.Zero);
                }

                // Redraw focus cues.
                //
                // For consistency with other PropertyGrid buttons, i.e. those opening system dialogs ("..."), that
                // always show visual cues when focused, we need to do the same for this custom button, painted as
                // a ComboBox control part (drop-down).
                if (Focused)
                {
                    dropDownButtonRect.Inflate(-1, -1);
                    ControlPaint.DrawFocusRectangle(pevent.Graphics, dropDownButtonRect, ForeColor, BackColor);
                }
            }
        }
Esempio n. 18
0
        /// <summary>
        ///  [See win32 equivalent.]
        /// </summary>
        public unsafe Size GetPartSize(IDeviceContext dc, Rectangle bounds, ThemeSizeType type)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Valid values are 0x0 to 0x2
            if (!ClientUtils.IsEnumValid(type, (int)type, (int)ThemeSizeType.Minimum, (int)ThemeSizeType.Draw))
            {
                throw new InvalidEnumArgumentException(nameof(type), (int)type, typeof(ThemeSizeType));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            RECT boundsRect = bounds;

            _lastHResult = GetThemePartSize(this, hdc, Part, State, &boundsRect, type, out Size size);
            return(size);
        }
Esempio n. 19
0
        protected void DrawCheckBackgroundFlat(PaintEventArgs e, Rectangle bounds, Color borderColor, Color checkBackground)
        {
            Color field  = checkBackground;
            Color border = borderColor;

            if (!Control.Enabled)
            {
                // If we are not in HighContrast mode OR we opted into the legacy behavior
                if (!SystemInformation.HighContrast)
                {
                    border = ControlPaint.ContrastControlDark;
                }

                // Otherwise we are in HighContrast mode
                field = SystemColors.Control;
            }

            double scale = GetDpiScaleRatio();

            using var hdc        = new DeviceContextHdcScope(e);
            using var borderPen  = new Gdi32.CreatePenScope(border);
            using var fieldBrush = new Gdi32.CreateBrushScope(field);

            if (scale > 1.1)
            {
                // In high DPI mode when we draw an ellipse as three rectangles, the quality of ellipse is poor. Draw
                // it directly as an ellipse.
                bounds.Width--;
                bounds.Height--;
                hdc.DrawAndFillEllipse(borderPen, fieldBrush, bounds);
                bounds.Inflate(-1, -1);
            }
            else
            {
                DrawAndFillEllipse(hdc, borderPen, fieldBrush, bounds);
            }
        }
Esempio n. 20
0
        /// <summary>
        ///  [See win32 equivalent.]
        ///  Returns null if the returned font was not true type, since GDI+ does not support it.
        /// </summary>
        public Font?GetFont(IDeviceContext dc, FontProperty prop)
        {
            if (dc is null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            if (!ClientUtils.IsEnumValid_NotSequential(prop, (int)prop, (int)FontProperty.TextFont, (int)FontProperty.GlyphFont))
            {
                throw new InvalidEnumArgumentException(nameof(prop), (int)prop, typeof(FontProperty));
            }

            using var hdc = new DeviceContextHdcScope(dc);
            _lastHResult  = GetThemeFont(this, hdc, Part, State, (int)prop, out User32.LOGFONTW logfont);

            // Check for a failed HR.
            if (!_lastHResult.Succeeded())
            {
                return(null);
            }

            try
            {
                return(Font.FromLogFont(logfont));
            }
            catch (Exception e)
            {
                if (ClientUtils.IsCriticalException(e))
                {
                    throw;
                }

                // Looks like the font was not true type
                return(null);
            }
        }
            internal ColorData Calculate()
            {
                ColorData colors = new ColorData(this)
                {
                    ButtonFace = _backColor
                };

                if (_backColor == SystemColors.Control)
                {
                    colors.ButtonShadow     = SystemColors.ControlDark;
                    colors.ButtonShadowDark = SystemColors.ControlDarkDark;
                    colors.Highlight        = SystemColors.ControlLightLight;
                }
                else
                {
                    if (!HighContrast)
                    {
                        colors.ButtonShadow     = ControlPaint.Dark(_backColor);
                        colors.ButtonShadowDark = ControlPaint.DarkDark(_backColor);
                        colors.Highlight        = ControlPaint.LightLight(_backColor);
                    }
                    else
                    {
                        colors.ButtonShadow     = ControlPaint.Dark(_backColor);
                        colors.ButtonShadowDark = ControlPaint.LightLight(_backColor);
                        colors.Highlight        = ControlPaint.LightLight(_backColor);
                    }
                }

                colors.WindowDisabled = HighContrast ? SystemColors.GrayText : colors.ButtonShadow;

                const float lowlight = .1f;
                float       adjust   = 1 - lowlight;

                if (colors.ButtonFace.GetBrightness() < .5)
                {
                    adjust = 1 + lowlight * 2;
                }

                colors.LowButtonFace = Color.FromArgb(
                    Adjust255(adjust, colors.ButtonFace.R),
                    Adjust255(adjust, colors.ButtonFace.G),
                    Adjust255(adjust, colors.ButtonFace.B));

                adjust = 1 - lowlight;
                if (colors.Highlight.GetBrightness() < .5)
                {
                    adjust = 1 + lowlight * 2;
                }

                colors.LowHighlight = Color.FromArgb(
                    Adjust255(adjust, colors.Highlight.R),
                    Adjust255(adjust, colors.Highlight.G),
                    Adjust255(adjust, colors.Highlight.B));

                if (HighContrast && _backColor != SystemColors.Control)
                {
                    colors.Highlight = colors.LowHighlight;
                }

                colors.WindowFrame = _foreColor;

                if (colors.ButtonFace.GetBrightness() < .5)
                {
                    colors.ConstrastButtonShadow = colors.LowHighlight;
                }
                else
                {
                    colors.ConstrastButtonShadow = colors.ButtonShadow;
                }

                if (!Enabled)
                {
                    colors.WindowText = colors.WindowDisabled;
                    if (HighContrast)
                    {
                        colors.WindowFrame  = colors.WindowDisabled;
                        colors.ButtonShadow = colors.WindowDisabled;
                    }
                }
                else
                {
                    colors.WindowText = colors.WindowFrame;
                }

                using var hdc = new DeviceContextHdcScope(_deviceContext, applyGraphicsState: false);

                colors.ButtonFace            = hdc.FindNearestColor(colors.ButtonFace);
                colors.ButtonShadow          = hdc.FindNearestColor(colors.ButtonShadow);
                colors.ButtonShadowDark      = hdc.FindNearestColor(colors.ButtonShadowDark);
                colors.ConstrastButtonShadow = hdc.FindNearestColor(colors.ConstrastButtonShadow);
                colors.WindowText            = hdc.FindNearestColor(colors.WindowText);
                colors.Highlight             = hdc.FindNearestColor(colors.Highlight);
                colors.LowHighlight          = hdc.FindNearestColor(colors.LowHighlight);
                colors.LowButtonFace         = hdc.FindNearestColor(colors.LowButtonFace);
                colors.WindowFrame           = hdc.FindNearestColor(colors.WindowFrame);
                colors.WindowDisabled        = hdc.FindNearestColor(colors.WindowDisabled);

                return(colors);
            }
Esempio n. 22
0
 internal static Rectangle DrawPopupBorder(PaintEventArgs e, Rectangle r, ColorData colors)
 {
     using var hdc = new DeviceContextHdcScope(e);
     return(DrawPopupBorder(hdc, r, colors));
 }
Esempio n. 23
0
 internal static Rectangle DrawPopupBorder(Graphics g, Rectangle r, ColorData colors)
 {
     using var hdc = new DeviceContextHdcScope(g);
     return(DrawPopupBorder(hdc, r, colors));
 }
        public void CreateWithGraphicsBasedOnImageAppliesRequestedParameters()
        {
            using Bitmap b   = new Bitmap(10, 10);
            using Graphics g = Graphics.FromImage(b);

            Rectangle clipRectangle = new Rectangle(1, 1, 5, 5);

            using Region r = new Region(clipRectangle);
            g.Clip         = r;

            Matrix transform = new Matrix();

            transform.Translate(1.0f, 2.0f);
            g.Transform = transform;

            // Just the translation transform
            using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.TranslateTransform))
            {
                Gdi32.GetViewportOrgEx(scope, out Point origin);
                Assert.Equal(new Point(1, 2), origin);

                RECT       clipRect   = default;
                RegionType regionType = Gdi32.GetClipBox(scope, ref clipRect);
                Assert.Equal(RegionType.SIMPLEREGION, regionType);
                Assert.Equal(new Rectangle(-1, -2, 10, 10), (Rectangle)clipRect);

                Assert.Equal(g, scope.DeviceContext);
            }

            // Just the clipping
            using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.Clipping))
            {
                Gdi32.GetViewportOrgEx(scope, out Point origin);
                Assert.Equal(new Point(0, 0), origin);

                RECT       clipRect   = default;
                RegionType regionType = Gdi32.GetClipBox(scope, ref clipRect);
                Assert.Equal(RegionType.SIMPLEREGION, regionType);
                Assert.Equal(clipRectangle, (Rectangle)clipRect);

                Assert.Equal(g, scope.DeviceContext);
            }

            // Both
            using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.All))
            {
                Gdi32.GetViewportOrgEx(scope, out Point origin);
                Assert.Equal(new Point(1, 2), origin);

                RECT       clipRect   = default;
                RegionType regionType = Gdi32.GetClipBox(scope, ref clipRect);
                Assert.Equal(RegionType.SIMPLEREGION, regionType);
                Assert.Equal(new Rectangle(0, -1, 5, 5), (Rectangle)clipRect);

                Assert.Equal(g, scope.DeviceContext);
            }

            // Nothing
            using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.None))
            {
                Gdi32.GetViewportOrgEx(scope, out Point origin);
                Assert.Equal(new Point(0, 0), origin);

                RECT       clipRect   = default;
                RegionType regionType = Gdi32.GetClipBox(scope, ref clipRect);
                Assert.Equal(RegionType.SIMPLEREGION, regionType);
                Assert.Equal(new Rectangle(0, 0, 10, 10), (Rectangle)clipRect);

                Assert.Equal(g, scope.DeviceContext);
            }

            // Validating we've unlocked the graphics object
            g.DrawLine(Pens.DarkBlue, default, default);