未完成的控件
using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace ImageControls { /// <summary> /// 控件 /// </summary> public class ShapeEx : Control { #region 字段 private Color _BackColor; //背景颜色 /// <summary> /// 必需的设计器变量。 /// </summary> private Color _BorderColor; //边框颜色 private Point _MouseLocation; private bool _ReSizeble; //是否可调整大小 private int _SelectSelctedIndex; //0-8,0:SizeAll private int _SelfHeight; private Point _SelfLocation; private int _SelfWidth; private Rectangle _rectBottomSelector; private Rectangle _rectLeftBottomSelector; private Rectangle _rectLeftSelector; private Rectangle _rectLeftTopSelector; private Rectangle _rectRightBottomSelector; private Rectangle _rectRightSelector; private Rectangle _rectRightTopSelector; private Rectangle _rectTopSelector; private Container components; #region modify by anby private float _ShapeExAngle; //控件的旋转角度 private int _ShapeExIsFocus; //0表示没有获取焦点,1表示获取焦点 #endregion #endregion #region 构造函数 public ShapeEx() { // 该调用是 Windows.Forms 窗体设计器所必需的。 InitializeComponent(); } #endregion #region 属性 [DefaultValue("Black"), Description("边框颜色"), Category("Appearance")] public Color BorderColor { get { // Insert code here. return _BorderColor; } set { _BorderColor = value; Invalidate(); } } [Description("控件ID号,自增长"), Category("Appearance")] public int ShapeExControlID { get; set; } [Description("用于连接外部控件ID"), Category("Appearance")] public int ShapeExJoinID { get; set; } [DefaultValue("Control"), Description("背景颜色"), Category("Appearance")] public override Color BackColor { get { // Insert code here. return _BackColor; } set { _BackColor = value; Invalidate(); } } [DefaultValue(false), Description("运行中控件大小是否可拖拽编辑"), Category("Behavior")] public bool ReSizeble { get { // Insert code here. return _ReSizeble; } set { _ReSizeble = value; Invalidate(); } } [Description("控件选择区域"), Category("Behavior")] public Rectangle SelectRectangle { get { var selectRectangler = new Rectangle(); selectRectangler.X = Location.X + 7; selectRectangler.Y = Location.Y + 7; selectRectangler.Height = Height - 15; selectRectangler.Width = Width - 15; return selectRectangler; } } /// <summary> /// 是否被获取焦点 /// </summary> [Description("控件是否获取焦点"), Category("Focus")] public int ShapeExIsFocus { get { return _ShapeExIsFocus; } set { _ShapeExIsFocus = value; } } [Description("控件旋转角度"), Category("Angle")] public float ShapeExAngle { get { return _ShapeExAngle; } set { _ShapeExAngle = value; this.Invalidate(); this.Visible = false; this.Visible = true; } } //CreateParams protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x00000020; return cp; } } #endregion #region 私有方法 private void DrawSelector(Graphics graphics,Rectangle rect,Point[] Points) { //graphics.TranslateTransform(Pcenter.X, Pcenter.Y); //graphics.RotateTransform(_ShapeExAngle); ////恢复绘图平面在水平和垂直方向的平移 rPoints[0] //graphics.TranslateTransform(-Pcenter.X, -Pcenter.Y); var SelectorPen = new SolidBrush(Color.White); var borderPen = new Pen(_BorderColor, 1); try { //实心 Point[] LeftPoints = RPoints(getPoint(rect.X - 7, Height / 2 - 3, 6, 6)); graphics.FillClosedCurve(SelectorPen, LeftPoints); Point[] TopPoints = RPoints(getPoint(Width / 2 - 3, rect.Y - 7, 6, 6)); graphics.FillClosedCurve(SelectorPen, TopPoints); Point[] RightPoints = RPoints(getPoint(rect.X + rect.Width, Height / 2 - 3, 6, 6)); graphics.FillClosedCurve(SelectorPen, RightPoints); Point[] BottomPoints = RPoints(getPoint(Width / 2 - 3, rect.Y + rect.Height, 6, 6)); graphics.FillClosedCurve(SelectorPen, BottomPoints); Point[] LeftTopPoints = RPoints(getPoint(rect.X - 7, rect.Y - 7, 6, 6)); graphics.FillClosedCurve(SelectorPen, LeftTopPoints); Point[] RightTopPoints =RPoints(getPoint(rect.X + rect.Width, rect.Y - 7, 6, 6)); graphics.FillClosedCurve(SelectorPen, RightTopPoints); Point[] RightBottomPoints = RPoints(getPoint(rect.X + rect.Width, rect.Y + rect.Height, 6, 6)); graphics.FillClosedCurve(SelectorPen, RightBottomPoints); Point[] LeftBottomPoints = RPoints(getPoint(rect.X - 7, rect.Y + rect.Height, 6, 6)); graphics.FillClosedCurve(SelectorPen, LeftBottomPoints); //边框 _rectLeftSelector.X = rect.X-7; _rectLeftSelector.Y =Height/2-3; _rectLeftSelector.Height = 6; _rectLeftSelector.Width = 6; var leftRpoints = RPoints(getPoint(_rectLeftSelector.X, _rectLeftSelector.Y, 6, 6)); graphics.DrawPolygon(borderPen, leftRpoints); _rectLeftSelector.X = leftRpoints[0].X; _rectLeftSelector.Y = leftRpoints[0].Y; //graphics.DrawRectangle(borderPen, _rectLeftSelector); _rectTopSelector.X = Width/2 - 3; _rectTopSelector.Y =rect.Y-7; _rectTopSelector.Height = 6; _rectTopSelector.Width = 6; var topRpoints = RPoints(getPoint(_rectTopSelector.X, _rectTopSelector.Y, 6, 6)); graphics.DrawPolygon(borderPen, topRpoints); _rectTopSelector.X = topRpoints[0].X; _rectTopSelector.Y = topRpoints[0].Y; //graphics.DrawRectangle(borderPen, _rectTopSelector); _rectRightSelector.X = rect.X+rect.Width; _rectRightSelector.Y = Height/2-3; _rectRightSelector.Height = 6; _rectRightSelector.Width = 6; var rightRpoints = RPoints(getPoint(_rectRightSelector.X, _rectRightSelector.Y, 6, 6)); graphics.DrawPolygon(borderPen, rightRpoints); _rectRightSelector.X = rightRpoints[0].X; _rectRightSelector.Y = rightRpoints[0].Y; //graphics.DrawRectangle(borderPen, _rectRightSelector); _rectBottomSelector.X = Width/2-3; _rectBottomSelector.Y = rect.Y+rect.Height; _rectBottomSelector.Height = 6; _rectBottomSelector.Width = 6; var bottomRpoints = RPoints(getPoint(_rectBottomSelector.X, _rectBottomSelector.Y, 6, 6)); graphics.DrawPolygon(borderPen, bottomRpoints); _rectBottomSelector.X = bottomRpoints[0].X; _rectBottomSelector.Y = bottomRpoints[0].Y; ////graphics.DrawRectangle(borderPen, _rectBottomSelector); _rectLeftTopSelector.X = rect.X-7; _rectLeftTopSelector.Y = rect.Y-7; _rectLeftTopSelector.Width = 6; _rectLeftTopSelector.Height = 6; var lefttopRpoints = RPoints(getPoint(_rectLeftTopSelector.X, _rectLeftTopSelector.Y, 6, 6)); graphics.DrawPolygon(borderPen, lefttopRpoints); _rectLeftTopSelector.X = lefttopRpoints[0].X; _rectLeftTopSelector.Y = lefttopRpoints[0].Y; //graphics.DrawRectangle(borderPen, _rectLeftTopSelector); _rectRightTopSelector.X = rect.X+rect.Width; _rectRightTopSelector.Y = rect.Y-7; _rectRightTopSelector.Width = 6; _rectRightTopSelector.Height = 6; var righttopRpoints= RPoints(getPoint(_rectRightTopSelector.X, _rectRightTopSelector.Y, 6, 6)); graphics.DrawPolygon(borderPen, righttopRpoints); _rectRightTopSelector.X = righttopRpoints[0].X; _rectRightTopSelector.Y = righttopRpoints[0].Y; //graphics.DrawRectangle(borderPen, _rectRightTopSelector); _rectRightBottomSelector.X = rect.X + rect.Width; _rectRightBottomSelector.Y = rect.Y+rect.Height; _rectRightBottomSelector.Width = 6; _rectRightBottomSelector.Height = 6; var rightbottomRpoints = RPoints(getPoint(_rectRightBottomSelector.X, _rectRightBottomSelector.Y, 6, 6)); graphics.DrawPolygon(borderPen, rightbottomRpoints); _rectRightBottomSelector.X = rightbottomRpoints[0].X; _rectRightBottomSelector.Y = rightbottomRpoints[0].Y; //graphics.DrawRectangle(borderPen, _rectRightBottomSelector); _rectLeftBottomSelector.X = rect.X-7; _rectLeftBottomSelector.Y = rect.Y + rect.Height; _rectLeftBottomSelector.Width = 6; _rectLeftBottomSelector.Height = 6; var leftbottompointRPoints = RPoints(getPoint(_rectLeftBottomSelector.X, _rectLeftBottomSelector.Y, 6, 6)); graphics.DrawPolygon(borderPen,leftbottompointRPoints); _rectLeftBottomSelector.X = leftbottompointRPoints[0].X; _rectLeftBottomSelector.Y = leftbottompointRPoints[0].Y; //graphics.DrawRectangle(borderPen, _rectLeftBottomSelector); } catch (Exception E) { throw E; } finally { SelectorPen.Dispose(); borderPen.Dispose(); } } public PointF Pcenter = new PointF(); public Point[] rPoints = null; private PointF center = new PointF(); private void ReDrawControl(Graphics graphics) { try { var borderPen = new Pen(_BorderColor, 1); //绘制边框 var rectBorder = new Rectangle(); rectBorder.X = 7; rectBorder.Y = 7; rectBorder.Height = Height - 15; rectBorder.Width = Width - 15; center = new PointF(this.Width/2, this.Height/2); //算出要平移的坐标 Point RationPoint = new Point((int)(center.X - rectBorder.Width / 2), (int)(center.Y - rectBorder.Height / 2)); //要绘制的矩形 var picRect = new RectangleF(RationPoint.X, RationPoint.Y, (float)rectBorder.Width, (float)rectBorder.Height); //圆心坐标 Pcenter = new PointF(picRect.X + picRect.Width/2, picRect.Y + picRect.Height/2); #region 最后修改 PointF leftToppoint = new PointF(picRect.X,picRect.Y); PointF leftBottompoint = new PointF(picRect.X, (picRect.Y + picRect.Height)); PointF rightToppoint = new PointF((picRect.X + picRect.Width), picRect.Y); PointF rightBottompoint = new PointF((picRect.X + picRect.Width), (picRect.Y + picRect.Height)); rPoints = RPoints(Point.Ceiling(leftToppoint),Point.Ceiling(rightToppoint), Point.Ceiling(rightBottompoint), Point.Ceiling(leftBottompoint)); RectangleF controlRect = new RectangleF(this.Location.X, this.Location.Y, this.Width, this.Height); getNewRectangle(rPoints); graphics.DrawPolygon(borderPen, rPoints); #endregion #region 旋转内,但是无法获取旋转后的坐标,程序失控 // //绘图平面以图片的中心点旋转 //graphics.TranslateTransform(Pcenter.X, Pcenter.Y); //graphics.RotateTransform(_ShapeExAngle); ////恢复绘图平面在水平和垂直方向的平移 //graphics.TranslateTransform(-Pcenter.X, -Pcenter.Y); //绘制图片 //graphics.DrawRectangle(borderPen, Rectangle.Ceiling(picRect)); //重置绘图平面的所有变换 //graphics.ResetTransform(); #endregion #region 图片旋转 图片超出边界 ////圆心坐标 //var center = new PointF(rectBorder.Width/2, rectBorder.Height/2); ////矩形左上坐标 //float offsetX = 0; //float offsetY = 0; //offsetX = center.X - rectBorder.Width/2; //offsetY = center.Y - rectBorder.Height/2; ////要画的图 //var picRect = new RectangleF(offsetX, offsetY, rectBorder.Width, rectBorder.Height); //var Pcenter = new PointF(picRect.X + picRect.Width/2, picRect.Y + picRect.Height/2); ////让图片绕中心旋转一周 ////for (int i = 0; i < 361; i += 10) ////{ //var changeRect = new Rectangle((int) picRect.X, (int) picRect.Y, (int) picRect.Width, // (int) picRect.Height); ////绘图平面以图片的中心点旋转 //graphics.TranslateTransform(Pcenter.X, Pcenter.Y); //graphics.RotateTransform(_ShapeExAngle); ////恢复绘图平面在水平和垂直方向的平移 //graphics.TranslateTransform(-Pcenter.X, -Pcenter.Y); ////绘制图片并延时 //graphics.DrawRectangle(borderPen, changeRect); ////重置绘图平面的所有变换 //graphics.ResetTransform(); ////} #endregion //绘制编辑框 if (_ReSizeble) { DrawSelector(graphics,Rectangle.Ceiling(picRect),rPoints); } } catch (Exception E) { throw E; } finally { graphics.Dispose(); } } /// <summary> /// 根据数组坐标获取新的矩形 /// </summary> /// <param name="rPoints"></param> private void getNewRectangle(Point[] rPoints) { try { int maxCoorX = getPointCoorX(rPoints, true); int minCoorX = getPointCoorX(rPoints, false); int maxCoorY = getPointCoorY(rPoints, true); int minCoorY = getPointCoorY(rPoints, false); //获得width和height double width = Math.Sqrt(maxCoorX*maxCoorX + minCoorX*minCoorX); double height = Math.Sqrt(maxCoorY*maxCoorY + minCoorY*minCoorY); _SelfWidth = (int) width; _SelfHeight = (int) height; } catch (Exception) { } } private PointF[] getPointF(int x, int y, int Width, int Height) { var point1 = new PointF(x, y); var point2 = new PointF(x + Width, y); var point3 = new PointF(x + Width, y + Height); var point4 = new PointF(x, y + Height); PointF[] points = {point1, point2, point3, point4}; return points; } private Point[] getPoint(int x, int y, int Width, int Height) { var point1 = new Point(x, y); var point2 = new Point(x + Width, y); var point3 = new Point(x + Width, y + Height); var point4 = new Point(x, y + Height); Point[] points = { point1, point2, point3, point4 }; return points; } protected override void Dispose(bool disposing) { if (disposing) { if (components != null) components.Dispose(); } base.Dispose(disposing); } #endregion #region 组件设计器生成的代码 private void InitializeComponent() { components = new Container(); Resize += ShapeEx_Resize; MouseDown += ShapeEx_MouseDown; MouseMove += ShapeEx_MouseMove; MouseLeave += ShapeEx_MouseLeave; MouseUp += ShapeEx_MouseUp; //this.GotFocus += new EventHandler(ShapeEx_GotFocus); //this.LostFocus += new EventHandler(ShapeEx_LostFocus); _ShapeExAngle = 30; _BorderColor = Color.Black; _BackColor = Color.FromName("Control"); _ReSizeble = false; _SelectSelctedIndex = -1; SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true); BackColor = Color.Transparent; } #endregion #region 事件 protected override void OnPaint(PaintEventArgs pe) { base.OnPaint(pe); ReDrawControl(pe.Graphics); } private void ShapeEx_Resize(object sender, EventArgs e) { if (Width < 16 || Height < 16) { Width = 16; Height = 16; } Invalidate(); } private void ShapeEx_MouseDown(object sender, MouseEventArgs e) { _ShapeExIsFocus = 1; if (_ReSizeble) { if (_rectLeftSelector.Contains(e.X, e.Y) || _rectRightSelector.Contains(e.X, e.Y) || _rectTopSelector.Contains(e.X, e.Y) || _rectBottomSelector.Contains(e.X, e.Y) || _rectLeftTopSelector.Contains(e.X, e.Y) || _rectRightTopSelector.Contains(e.X, e.Y) || _rectRightBottomSelector.Contains(e.X, e.Y) || _rectLeftBottomSelector.Contains(e.X, e.Y)) { if (_rectLeftTopSelector.Contains(e.X, e.Y)) { Cursor = Cursors.SizeNWSE; _SelectSelctedIndex = 1; } if (_rectTopSelector.Contains(e.X, e.Y)) { Cursor = Cursors.SizeNS; _SelectSelctedIndex = 2; } if (_rectRightTopSelector.Contains(e.X, e.Y)) { Cursor = Cursors.SizeNESW; _SelectSelctedIndex = 3; } if (_rectRightSelector.Contains(e.X, e.Y)) { Cursor = Cursors.SizeWE; _SelectSelctedIndex = 4; } if (_rectRightBottomSelector.Contains(e.X, e.Y)) { Cursor = Cursors.SizeNWSE; _SelectSelctedIndex = 5; } if (_rectBottomSelector.Contains(e.X, e.Y)) { Cursor = Cursors.SizeNS; _SelectSelctedIndex = 6; } if (_rectLeftBottomSelector.Contains(e.X, e.Y)) { Cursor = Cursors.SizeNESW; _SelectSelctedIndex = 7; } if (_rectLeftSelector.Contains(e.X, e.Y)) { Cursor = Cursors.SizeWE; _SelectSelctedIndex = 8; } } else { Cursor = Cursors.SizeAll; _SelectSelctedIndex = 0; } _SelfLocation.X = Location.X; _SelfLocation.Y = Location.Y; _MouseLocation.X = Cursor.Position.X; _MouseLocation.Y = Cursor.Position.Y; _SelfWidth = Width; _SelfHeight = Height; } } private void ShapeEx_MouseMove(object sender, MouseEventArgs e) { //move and resize switch (_SelectSelctedIndex) { case 0: Location = new Point(Cursor.Position.X - (_MouseLocation.X - _SelfLocation.X), Cursor.Position.Y - (_MouseLocation.Y - _SelfLocation.Y)); break; case 1: Height = _SelfHeight - (Cursor.Position.Y - _MouseLocation.Y); Width = _SelfWidth - (Cursor.Position.X - _MouseLocation.X); Location = new Point(Cursor.Position.X - _MouseLocation.X + _SelfLocation.X, Cursor.Position.Y - _MouseLocation.Y + _SelfLocation.Y); break; case 2: Height = _SelfHeight - (Cursor.Position.Y - _MouseLocation.Y); Location = new Point(_SelfLocation.X, Cursor.Position.Y - _MouseLocation.Y + _SelfLocation.Y); break; case 3: Height = _SelfHeight - (Cursor.Position.Y - _MouseLocation.Y); Width = _SelfWidth + (Cursor.Position.X - _MouseLocation.X); Location = new Point(_SelfLocation.X, Cursor.Position.Y - (_MouseLocation.Y - _SelfLocation.Y)); break; case 4: Width = _SelfWidth + (Cursor.Position.X - _MouseLocation.X); break; case 5: Height = _SelfHeight + (Cursor.Position.Y - _MouseLocation.Y); Width = _SelfWidth + (Cursor.Position.X - _MouseLocation.X); break; case 6: Height = _SelfHeight + (Cursor.Position.Y - _MouseLocation.Y); break; case 7: Height = _SelfHeight + (Cursor.Position.Y - _MouseLocation.Y); Width = _SelfWidth - (Cursor.Position.X - _MouseLocation.X); Location = new Point(Cursor.Position.X - _MouseLocation.X + _SelfLocation.X, _SelfLocation.Y); break; case 8: Width = _SelfWidth - (Cursor.Position.X - _MouseLocation.X); Location = new Point(Cursor.Position.X - _MouseLocation.X + _SelfLocation.X, _SelfLocation.Y); break; } Invalidate(); } private void ShapeEx_MouseLeave(object sender, EventArgs e) { Cursor = Cursors.Default; _SelectSelctedIndex = -1; } private void ShapeEx_MouseUp(object sender, MouseEventArgs e) { _ShapeExIsFocus = 0; Cursor = Cursors.Default; _SelectSelctedIndex = -1; } /// <summary> /// 用于减少画面闪烁效果及刷新控件 /// </summary> /// <param name="e"></param> protected override void OnLocationChanged(EventArgs e) { Visible = false; Visible = true; } #endregion /// <summary> /// 对一个坐标点按照一个中心进行旋转 /// </summary> /// <param name="center">中心点</param> /// <param name="p1">要旋转的点</param> /// <param name="angle">旋转角度,笛卡尔直角坐标</param> /// <returns></returns> private Point PointRotate(Point center, Point p1, double angle) { Point tmp = new Point(); double angleHude = angle * Math.PI / 180;/*角度变成弧度*/ double x1 = (p1.X - center.X) * Math.Cos(angleHude) + (p1.Y - center.Y) * Math.Sin(angleHude) + center.X; double y1 = -(p1.X - center.X) * Math.Sin(angleHude) + (p1.Y - center.Y) * Math.Cos(angleHude) + center.Y; tmp.X = (int)x1; tmp.Y = (int)y1; return tmp; } /// <summary> /// 根据rectangle的4个顶点获取旋转后的坐标 /// </summary> /// <param name="leftToppoint">左上角坐标</param> /// <param name="leftBottompoint">左下脚坐标</param> /// <param name="rightToppoint">右上角坐标</param> /// <param name="rightBottompoint">右下角坐标</param> /// <returns>旋转后的4点坐标</returns> private Point[] RPoints(Point leftToppoint, Point rightToppoint, Point rightBottompoint, Point leftBottompoint) { //旋转后的点 Point rationleftToppoint = PointRotate(Point.Ceiling(Pcenter), leftToppoint, _ShapeExAngle); Point rationleftBottompoint = PointRotate(Point.Ceiling(Pcenter), leftBottompoint, _ShapeExAngle); Point rationrightToppoint = PointRotate(Point.Ceiling(Pcenter), rightToppoint, _ShapeExAngle); Point rationrightBottompoint = PointRotate(Point.Ceiling(Pcenter), rightBottompoint, _ShapeExAngle); Point[] rPoints = { rationleftToppoint, rationrightToppoint, rationrightBottompoint, rationleftBottompoint }; return rPoints; } /// <summary> /// 根据rectangle的4个顶点获取旋转后的坐标 /// </summary> /// <param name="points">左上角坐标,左下脚坐标,右上角坐标,右下角坐标 </param> /// <returns>旋转后的4点坐标</returns> private Point[] RPoints(Point[] points) { //旋转后的点 Point rationleftToppoint = PointRotate(Point.Ceiling(Pcenter), points[0], _ShapeExAngle); Point rationrightToppoint = PointRotate(Point.Ceiling(Pcenter), points[1], _ShapeExAngle); Point rationrightBottompoint = PointRotate(Point.Ceiling(Pcenter), points[2], _ShapeExAngle); Point rationleftBottompoint = PointRotate(Point.Ceiling(Pcenter), points[3], _ShapeExAngle); Point[] rPoints = { rationleftToppoint, rationrightToppoint, rationrightBottompoint, rationleftBottompoint }; return rPoints; } private int getPointCoorX (Point[] arr,bool isMax) { if (arr == null) { throw new Exception(); } int max = 0; int[] myarr = new int[5]; for (int i = 0; i < arr.Length - 1; i++) { myarr[i] = arr[i].X; } Array.Sort(myarr); if (isMax) { return myarr[myarr.Length - 1]; } else { return myarr[0]; } } private int getPointCoorY(Point[] arr,bool isMax) { if (arr == null) { throw new Exception(); } int max = 0; int[] myarr = new int[5]; for (int i = 0; i < arr.Length - 1; i++) { myarr[i] = arr[i].Y; } Array.Sort(myarr); if (isMax) { return myarr[myarr.Length - 1]; } else { return myarr[0]; } } } }