屏幕绘图的原理是,启动一个全屏窗体,将当前屏幕的截图作为背景图片,在窗体上进行绘制。
选择要绘制的屏幕:
[code lang="csharp"]Screen screen = Screen.PrimaryScreen;[/code]
全屏窗体
要启动全屏窗口,设置窗体如下属性:
[code lang="csharp"]this.FormBorderStyle = FormBorderStyle.None;//无边框 this.ShowInTaskbar = false; this.TopMost = true;//保持在最前面 this.Bounds = screen.Bounds;//设置正好铺满整个屏幕[/code]
屏幕拷贝
.NET2.0中提供了 Graphics.CopyFromScreen 方法,使屏幕拷贝代码很简洁。下面代码演示将主屏幕的截图写入到 Bitmap 实例。
[code lang="csharp"]Rectangle bounds = screen.Bounds; backImage = new Bitmap(bounds.Width, bounds.Height); Graphics g = Graphics.FromImage(backImage); g.CopyFromScreen(bounds.Location, new Point(0, 0), bounds.Size); g.Dispose();[/code]
记录鼠标轨迹
绘制的重载窗体的 OnMouseDown 、 OnMouseUp 和 OnMouseMove 方法,获取鼠标拖动的轨迹,用一个Point[] 数组存储一段曲线。当鼠标移动时,如果鼠标已经按下,添加鼠标坐标到曲线中。
因为绘制的各条曲线可能具有不同的颜色、线宽等属性,我们可以定义类存储曲线数据,如下:
[code lang="csharp"]///
/// 一条曲线的数据类。 ///
public class CurveData { Color color = Color.Black; float width = 1.0F; Point[] points; ///
/// 曲线的颜色 ///
public Color Color { get { return color; } } ///
/// 曲线的宽度 ///
public float Width { get { return width; } } ///
/// 绘制曲线所用的画笔。 ///
public Pen Pen { get { return new Pen(color,width); } } ///
/// 存储曲线中各个点的坐标。 ///
public Point[] Points { get { return points; } }
///
/// 构造函数。 ///
/// 曲线的颜色 /// 线条的宽度 /// 坐标点数据 public CurveData(Color color, float width,Point[] points) { this.color = color; this.width = width; this.points = points; } }[/code]
可以将各条曲线存储在 List<> 中,方便添加、删除等操作:
[code lang="csharp"]List curves = new List();[/code]
绘制数据
重载 OnPaint 方法,先绘制屏幕截图,再绘制各条曲线,就实现涂鸦功能了。效果如下图所示(图中曲线为标注效果):
需要注意的地方
1. 每当一个点被添加到曲线中,你只需要绘制从原曲线最后一个点到该点的线段即可。只有当屏幕刷新时才需要绘制所有曲线。
2. 一定要启用窗体的双缓冲设置(DoubleBuffered),以减少或避免屏幕闪烁。
转摘自: http://chuangen.name