话不多说 先看看效果吧
好吧 你想说这是截图?好吧其实就是、、- -!我本来就打算做重写我的截图程序只是还在做控件期间 就顺带的把 这个控件发上来了
这里 就当截图程序来说吧 反正把控件放大全屏化也就是截图了、、看到很多人问 截图的时候 怎么让周围暗下来、、
protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; if (this._Image != null) { g.DrawImage(this._Image, Point.Empty);//原图 using (SolidBrush sb = new SolidBrush(this._MaskColor)) { g.FillRectangle(sb, this.ClientRectangle);//遮罩 } if (!this._SelectedRectangle.IsEmpty) this.DrawSelectedRectangle(g);//选框 if (this._IsDrawMagnifier && m_bMouseHover && !_IsDrawed && !m_bMoving) this.DrawMagnifier(g, m_ptCurrent);//放大镜 } base.OnPaint(e); }上面是我OnPaint里面的代码 一个四个大的阶段 首先低下绘制原图 然后绘制一层遮罩(其实原图和遮罩何以混合成一张图这样就只绘制一次了) 如果有选择区域那么绘制选框(- -!在绘制选框的代码里有再次绘制一份选区大小的原图 这样就能看到明暗变化了) 然后就是放大镜的问题
接下来问题是 如何制作这个裁剪控件 首先不说业务问题 就绘制做一个样子而言 你得有八个顶点
private Rectangle[] m_rectDots = new Rectangle[8]; //八个控制点
//初始化顶点
for (int i = 0; i < 8; i++) {
m_rectDots[i].Size = new Size(5, 5);
}
//绘制选框
protected virtual void DrawSelectedRectangle(Graphics g) {
m_rectDots[0].Y = m_rectDots[1].Y = m_rectDots[2].Y
= this._SelectedRectangle.Y - 2;
m_rectDots[5].Y = m_rectDots[6].Y = m_rectDots[7].Y
= this._SelectedRectangle.Bottom - 2;
m_rectDots[0].X = m_rectDots[3].X = m_rectDots[5].X
= this._SelectedRectangle.X - 2;
m_rectDots[2].X = m_rectDots[4].X = m_rectDots[7].X
= this._SelectedRectangle.Right - 2;
m_rectDots[3].Y = m_rectDots[4].Y
= this._SelectedRectangle.Y + this._SelectedRectangle.Height / 2 - 2;
m_rectDots[1].X = m_rectDots[6].X
= this._SelectedRectangle.X + this._SelectedRectangle.Width / 2 - 2;
g.DrawImage(this._Image, this._SelectedRectangle,
this._SelectedRectangle, GraphicsUnit.Pixel);
g.DrawRectangle(Pens.Cyan,
this._SelectedRectangle.Left, this._SelectedRectangle.Top,
this._SelectedRectangle.Width - 1, this._SelectedRectangle.Height - 1);
foreach (Rectangle rect in m_rectDots)
g.FillRectangle(Brushes.Yellow, rect);
}
这里 八个顶点就有了 而且可以看到 这个方法在我的OnPaint里面有调用 然后要操作这些点 来拖动区域或者改变大小什么的 就需要控件的一些鼠标事件了 比如MouseDown事件 如果初次点下 那么你需要记录下这个点ptStart然后在MouseMove中就可以进行绘制了 因为有ptStart所以Move中就可以确定矩形框的大小 然后当鼠标抬起的时候确定这个大小 当然中间需要一些变量来标记一些东西 比如是否已经绘制了一个矩形框了什么的
其实 直接绘制矩形框什么的没有啥难度 因为确定两个点 就能确定大小了 重点在于 绘制了矩形框之后 如何改变他的大小 如果已经绘制好了一个矩形框 那么在MouseMove中 你就需要判断当前鼠标是不是在顶点上或者 区域里面 为什么?因为你需要判断 来设置鼠标应该显示箭头还是什么的啊、、、然后你需要在MouseDown里面判断 是不是是在某个点上点击的
//设置鼠标样式 protected virtual void SetCursorStyle(Point pt) { if (m_rectDots[0].Contains(pt) || m_rectDots[7].Contains(pt)) this.Cursor = Cursors.SizeNWSE; else if (m_rectDots[1].Contains(pt) || m_rectDots[6].Contains(pt)) this.Cursor = Cursors.SizeNS; else if (m_rectDots[2].Contains(pt) || m_rectDots[5].Contains(pt)) this.Cursor = Cursors.SizeNESW; else if (m_rectDots[3].Contains(pt) || m_rectDots[4].Contains(pt)) this.Cursor = Cursors.SizeWE; else if (this._SelectedRectangle.Contains(pt)) this.Cursor = Cursors.SizeAll; else this.Cursor = Cursors.Default; } //MouseDown中 if (this._IsDrawed) { this._IsDrawed = false; if (m_rectDots[0].Contains(e.Location)) { m_ptStart.X = this._SelectedRectangle.Right; m_ptStart.Y = this._SelectedRectangle.Bottom; } else if (m_rectDots[1].Contains(e.Location)) { m_ptStart.Y = this._SelectedRectangle.Bottom; m_bChangeWidth = false; } else if (m_rectDots[2].Contains(e.Location)) { m_ptStart.X = this._SelectedRectangle.X; m_ptStart.Y = this._SelectedRectangle.Bottom; } else if (m_rectDots[3].Contains(e.Location)) { m_ptStart.X = this._SelectedRectangle.Right; m_bChangeHeight = false; } else if (m_rectDots[4].Contains(e.Location)) { m_ptStart.X = this._SelectedRectangle.X; m_bChangeHeight = false; } else if (m_rectDots[5].Contains(e.Location)) { m_ptStart.X = this._SelectedRectangle.Right; m_ptStart.Y = this._SelectedRectangle.Y; } else if (m_rectDots[6].Contains(e.Location)) { m_ptStart.Y = this._SelectedRectangle.Y; m_bChangeWidth = false; } else if (m_rectDots[7].Contains(e.Location)) { m_ptStart = this._SelectedRectangle.Location; } else if (this._SelectedRectangle.Contains(e.Location)) { m_bMoving = true; m_bChangeWidth = false; m_bChangeHeight = false; } else { this._IsDrawed = true; } }如果用户是在四个角上面点击的 其实很好处理 比如用户点击的是右下角的顶点来改变大小 那么请问 这个和刚才上面提到的初次绘制矩形框有什么区别?把ptStart重置为原本左上角的坐标 就相当于在左上角点下了 然后鼠标已经拖动到右下角的位置了而已、、当然 如果是点击的中间的点 就需要一些标志变量了
由于全部代码还是有点分量 加上注释 神马的还是有三百多接近四百行、、这里就单开页面上传全部代码
代码注释也很详细了 具体详情还是看代码吧、、