예제 #1
0
        private unsafe void CreatePen()
        {
            if (_width > 1)
            {
                // Geometric pen.
                // From MSDN: if width > 1, the style must be PS_NULL, PS_SOLID, or PS_INSIDEFRAME.
                _style |= Gdi32.PS.GEOMETRIC | Gdi32.PS.SOLID;
            }

            if (_wndBrush == null)
            {
                _nativeHandle = Gdi32.CreatePen(_style, _width, ColorTranslator.ToWin32(_color));
            }
            else
            {
                var lb = new Gdi32.LOGBRUSH
                {
                    lbColor = ColorTranslator.ToWin32(_wndBrush.Color),
                    lbStyle = Gdi32.BS.SOLID,
                    lbHatch = IntPtr.Zero
                };

                // Note: We currently don't support custom styles, that's why 0 and null for last two params.
                _nativeHandle = Gdi32.ExtCreatePen(_style, _width, ref lb, 0, null);
            }
        }
예제 #2
0
 public WindowsPen(DeviceContext dc, Gdi32.PS style, int width, Color color)
 {
     _style = style;
     _width = width;
     _color = color;
     _dc    = dc;
 }
        public void ControlPaint_DrawBorder_Inset_Rendering()
        {
            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            using Graphics graphics = Graphics.FromHdc((IntPtr)emf.HDC);

            Rectangle bounds = new Rectangle(10, 10, 10, 10);

            ControlPaint.DrawBorder(graphics, bounds, Color.Gray, ButtonBorderStyle.Inset);

            // For whatever reason GDI+ renders as polylines scaled 16x with a 1/16th world transform applied.
            // For test readability we'll transform the points from our coordinates to the logical coordinates.
            Matrix3x2 oneSixteenth = Matrix3x2.CreateScale(0.0625f);
            Matrix3x2 times16      = Matrix3x2.CreateScale(16.0f);

            // This is the default pen style GDI+ renders polylines with
            Gdi32.PS penStyle = Gdi32.PS.SOLID | Gdi32.PS.JOIN_ROUND | Gdi32.PS.COSMETIC | Gdi32.PS.ENDCAP_FLAT
                                | Gdi32.PS.JOIN_MITER | Gdi32.PS.GEOMETRIC;

            emf.Validate(
                state,
                // Top
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 10, 10, 19, 10),
                    State.Pen(16, ControlPaint.DarkDark(Color.Gray), penStyle),
                    State.Transform(oneSixteenth)),
                // Left
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 10, 10, 10, 19),
                    State.Pen(16, ControlPaint.DarkDark(Color.Gray), penStyle),
                    State.Transform(oneSixteenth)),
                // Bottom
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 10, 19, 19, 19),
                    State.Pen(16, ControlPaint.LightLight(Color.Gray), penStyle),
                    State.Transform(oneSixteenth)),
                // Right
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 19, 10, 19, 19),
                    State.Pen(16, ControlPaint.LightLight(Color.Gray), penStyle),
                    State.Transform(oneSixteenth)),
                // Top inset
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 11, 11, 18, 11),
                    State.Pen(16, ControlPaint.Light(Color.Gray), penStyle),
                    State.Transform(oneSixteenth)),
                // Left inset
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 11, 11, 11, 18),
                    State.Pen(16, ControlPaint.Light(Color.Gray), penStyle),
                    State.Transform(oneSixteenth))
                );
        }
        public void ControlPaint_DrawBorder_Dashed_Rendering()
        {
            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            using Graphics graphics = Graphics.FromHdc((IntPtr)emf.HDC);

            Rectangle bounds = new Rectangle(10, 10, 10, 10);

            ControlPaint.DrawBorder(graphics, bounds, Color.Pink, ButtonBorderStyle.Dashed);

            // For whatever reason GDI+ renders as polygons scaled 16x with a 1/16th world transform applied.
            Matrix3x2 oneSixteenth = Matrix3x2.CreateScale(0.0625f);

            // This is the default pen style GDI+ renders dotted lines with
            Gdi32.PS penStyle = Gdi32.PS.SOLID | Gdi32.PS.JOIN_ROUND | Gdi32.PS.COSMETIC | Gdi32.PS.ENDCAP_FLAT
                                | Gdi32.PS.JOIN_BEVEL | Gdi32.PS.GEOMETRIC;

            emf.Validate(
                state,
                Validate.PolyPolygon16(
                    new Rectangle(8, 8, 13, 13),
                    polyCount: 9,
                    State.Transform(oneSixteenth),
                    State.Pen(16, Color.Pink, penStyle),
                    State.Brush(Color.Pink, Gdi32.BS.SOLID)));
        }
예제 #5
0
        public WindowsPen(DeviceContext dc, Gdi32.PS style, int width, WindowsBrush windowsBrush)
        {
            Debug.Assert(windowsBrush != null, "null windowsBrush");

            _style    = style;
            _wndBrush = (WindowsBrush)windowsBrush.Clone();
            _width    = width;
            _color    = windowsBrush.Color;
            _dc       = dc;
        }
예제 #6
0
        public RectangleValidator(
            RECT bounds,
            Color penColor,
            Color brushColor,
            int penWidth                = 1,
            Gdi32.PS penStyle           = default,
            Gdi32.R2 rop2               = Gdi32.R2.COPYPEN,
            Gdi32.BKMODE backgroundMode = Gdi32.BKMODE.TRANSPARENT,
            Gdi32.BS brushStyle         = default,
            Flags validate              = default)
        {
            _bounds         = bounds;
            _brushColor     = brushColor;
            _brushStyle     = brushStyle;
            _penWidth       = penWidth;
            _penColor       = penColor;
            _penStyle       = penStyle;
            _rop2           = rop2;
            _backgroundMode = backgroundMode;

            if (validate != default)
            {
                _validate = validate;
                return;
            }

            // Default values for all of these are valid expectations so we always turn them on.
            _validate = Flags.Bounds | Flags.PenStyle | Flags.BrushStyle;

            if (penWidth != 0)
            {
                _validate |= Flags.PenWidth;
            }

            if (!penColor.IsEmpty)
            {
                _validate |= Flags.PenColor;
            }

            if (!brushColor.IsEmpty)
            {
                _validate |= Flags.BrushColor;
            }

            if (backgroundMode != default)
            {
                _validate |= Flags.BackgroundMode;
            }

            if (_rop2 != default)
            {
                _validate |= Flags.RopMode;
            }
        }
예제 #7
0
        public LineToValidator(
            Point from,
            Point to,
            Color penColor,
            int penWidth                = 1,
            Gdi32.PS penStyle           = default,
            Gdi32.R2 rop2               = Gdi32.R2.COPYPEN,
            Gdi32.BKMODE backgroundMode = Gdi32.BKMODE.TRANSPARENT,
            Flags validate              = default)
        {
            _from           = from;
            _to             = to;
            _penWidth       = penWidth;
            _penColor       = penColor;
            _penStyle       = penStyle;
            _rop2           = rop2;
            _backgroundMode = backgroundMode;

            if (validate != default)
            {
                _validate = validate;
                return;
            }

            // Default values for all of these are valid expectations so we always turn them on.
            _validate = Flags.From | Flags.To | Flags.PenStyle;

            if (penWidth != 0)
            {
                _validate |= Flags.PenWidth;
            }

            if (!penColor.IsEmpty)
            {
                _validate |= Flags.PenColor;
            }

            if (backgroundMode != default)
            {
                _validate |= Flags.BackgroundMode;
            }

            if (_rop2 != default)
            {
                _validate |= Flags.RopMode;
            }
        }
예제 #8
0
 internal static IEmfValidator LineTo(
     EasyPoint from,
     EasyPoint to,
     Color penColor,
     int penWidth                   = 1,
     Gdi32.PS penStyle              = default,
     Gdi32.R2 rop2Mode              = Gdi32.R2.COPYPEN,
     Gdi32.BKMODE backgroundMode    = Gdi32.BKMODE.TRANSPARENT,
     LineToValidator.Flags validate = default) => new LineToValidator(
     from,
     to,
     penColor,
     penWidth,
     penStyle,
     rop2Mode,
     backgroundMode,
     validate);
예제 #9
0
 internal static IEmfValidator Rectangle(
     RECT bounds,
     Color penColor,
     Color brushColor,
     int penWidth                      = 1,
     Gdi32.PS penStyle                 = default,
     Gdi32.R2 rop2                     = Gdi32.R2.COPYPEN,
     Gdi32.BKMODE backgroundMode       = Gdi32.BKMODE.TRANSPARENT,
     Gdi32.BS brushStyle               = default,
     RectangleValidator.Flags validate = default) => new RectangleValidator(
     bounds,
     penColor,
     brushColor,
     penWidth,
     penStyle,
     rop2,
     backgroundMode,
     brushStyle,
     validate);
        public void StatusStrip_RendersBorderCorrectly()
        {
            using Form form = new Form();
            using StatusStrip statusStrip = new StatusStrip
                  {
                      BackColor  = Color.Blue,
                      SizingGrip = false,
                      Renderer   = new ToolStripProfessionalRenderer(new CustomColorTable()),
                      Size       = new Size(200, 38)
                  };
            form.Controls.Add(statusStrip);

            // Force the handle creation
            Assert.NotEqual(IntPtr.Zero, form.Handle);
            Assert.NotEqual(IntPtr.Zero, statusStrip.Handle);

            // Create an Enhance Metafile into which we will render the control
            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            // Render the control
            statusStrip.PrintToMetafile(emf);

            Rectangle bounds         = statusStrip.Bounds;
            Rectangle bitBltBounds   = new Rectangle(bounds.X, 0, bounds.Width - 1, bounds.Height - 1);
            Rectangle polylineBounds = new Rectangle(bounds.X, 0, bounds.Width - 1, 15);

            // This is the default pen style GDI+ renders polylines with
            Gdi32.PS penStyle = Gdi32.PS.SOLID | Gdi32.PS.JOIN_ROUND | Gdi32.PS.COSMETIC | Gdi32.PS.ENDCAP_FLAT | Gdi32.PS.JOIN_MITER | Gdi32.PS.GEOMETRIC;

            emf.Validate(
                state,
                Validate.BitBltValidator(bitBltBounds, State.BrushColor(Color.Blue)),
                Validate.Polyline16(polylineBounds, null, State.Pen(16, Color.Green, penStyle))
                );

            var details = emf.RecordsToString();
        }
        public void DataGridView_GridColor_Rendering()
        {
            using Form form = new Form();

            // Only want to render one cell to validate
            using var dataGrid = new DataGridView
                  {
                      GridColor            = Color.Blue,
                      ColumnCount          = 1,
                      RowCount             = 1,
                      ColumnHeadersVisible = false,
                      RowHeadersVisible    = false
                  };

            form.Controls.Add(dataGrid);

            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            dataGrid.PrintToMetafile(emf);

            Assert.Equal(new Rectangle(0, 0, 240, 150), dataGrid.Bounds);
            Assert.Equal(new Size(100, 25), dataGrid[0, 0].Size);

            Rectangle bounds = dataGrid.Bounds;

            // For whatever reason GDI+ renders as polylines scaled 16x with a 1/16th world transform applied.
            // For test readability we'll transform the points from our coordinates to the logical coordinates.
            Matrix3x2 oneSixteenth = Matrix3x2.CreateScale(0.0625f);
            Matrix3x2 times16      = Matrix3x2.CreateScale(16.0f);

            // This is the default pen style GDI+ renders with
            Gdi32.PS penStyle = Gdi32.PS.SOLID | Gdi32.PS.JOIN_ROUND | Gdi32.PS.COSMETIC | Gdi32.PS.ENDCAP_FLAT
                                | Gdi32.PS.JOIN_MITER | Gdi32.PS.GEOMETRIC;

            // Don't really care about the bounds, just the actual shapes/lines
            emf.Validate(
                state,
                // The datagrid background
                Validate.Polygon16(
                    bounds: null,
                    PointArray(times16, 1, 1, 1, 149, 239, 149, 239, 1, 1, 1),
                    State.Pen(1, Color.Empty, Gdi32.PS.NULL),
                    State.Brush(SystemColors.ButtonShadow, Gdi32.BS.SOLID),
                    State.Transform(oneSixteenth)),
                // Left cell border
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 1, 1, 1, 26),
                    State.Pen(16, Color.Blue, penStyle),
                    State.Transform(oneSixteenth)),
                // Right cell border
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 101, 1, 101, 26),
                    State.Pen(16, Color.Blue, penStyle),
                    State.Transform(oneSixteenth)),
                // Top cell border
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 1, 1, 101, 1),
                    State.Pen(16, Color.Blue, penStyle),
                    State.Transform(oneSixteenth)),
                // Bottom cell border
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 1, 26, 101, 26),
                    State.Pen(16, Color.Blue, penStyle),
                    State.Transform(oneSixteenth)),
                // Cell background
                Validate.Polygon16(
                    bounds: null,
                    PointArray(times16, 2, 2, 2, 26, 101, 26, 101, 2, 2, 2),
                    State.Pen(1, Color.Empty, Gdi32.PS.NULL),
                    State.Brush(SystemColors.ButtonHighlight, Gdi32.BS.SOLID),
                    State.Transform(oneSixteenth)),
                // Datagrid border
                Validate.Polygon16(
                    bounds: null,
                    PointArray(times16, 0, 0, 239, 0, 239, 149, 0, 149),
                    State.Pen(16, SystemColors.Desktop, penStyle),
                    State.Brush(Color.Empty, Gdi32.BS.NULL),
                    State.Transform(oneSixteenth)));
        }
 public PenStyleValidator(Gdi32.PS penStyle) => _penStyle = penStyle;
예제 #13
0
파일: State.cs 프로젝트: hughbe/winforms
 internal static IStateValidator PenStyle(Gdi32.PS penStyle) => new PenStyleValidator(penStyle);
예제 #14
0
파일: State.cs 프로젝트: hughbe/winforms
 internal static IStateValidator Pen(int penWidth, Color penColor, Gdi32.PS penStyle)
 => new PenValidator(penWidth, penColor, penStyle);
예제 #15
0
 public PenValidator(int penWidth, Color penColor, Gdi32.PS penStyle)
 {
     _penWidth = penWidth;
     _penColor = penColor;
     _penStyle = penStyle;
 }