由于最近项目里要有一个截图功能,花了几天时间写了个小程序,封装了3个不同截屏方式,希望能给有类似需求的园友提供一点点参考
功能概述:
- 全屏截取
- 区域截取
- 窗体截取
效果入下图示:
实现方法概述
全屏截图
/// <summary> /// 获取全屏截图 /// </summary> /// <returns>截图</returns> publicImage GetFullScreenImage() { Imageimage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphicsg = Graphics.FromImage(image); g.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.PrimaryScreen.Bounds.Size); returnimage; }
区域截图
将Form设置为半透明状态,用户移动、拖拽窗体,选择区域后双击截图,Esc或鼠标右键退出。主要代码如下:
//双击获取截图 privatevoid GetScreenImage() { _image = new Bitmap(this.Width, this.Height); Graphicsg = Graphics.FromImage(_image); g.CopyFromScreen(this.Location, new Point(0, 0), new Size(this.Width, this.Height)); this.DialogResult= DialogResult.OK; }
窗体截取
1,根据鼠标位置获取目标窗体句柄
[DllImport("user32.dll")] public static extern IntPtr WindowFromPoint(Pointpoint);
2,绘制窗体外边框,使用户知道现在要截取的窗体
调用gdi32.dll里面的方法绘制边框,代码较多,请参见源码
3,截图
根据得到窗体的句柄通过如下方法获得窗体的位置和大小
[DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtrhWnd, ref RECTlpRect);
被选择的窗体可能不是最前端的窗体,为了完整截取窗体,在截取之前,先把窗体通过以下方法设置为最前端窗体
[DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd);
截图方法与其他两种截图方法一样,都是用Graphics类的CopyFromScreen方法完成的
组件使用方法
ScreenShot类中封装了3个方法分别用于全屏截取、区域截取和窗体截取,使用方法如下:
1,全屏截取
_image= _screenShot.GetFullScreenImage();
2,区域截取
_image= _screenShot.GetRangeImage();
3,窗体截取
需要添加一个事件:AfterCapture,然后再调用OpenWindowImageCaptureForm方法。在事件参数里得到Image对象
if (_screenShot.AfterCapture == null) { _screenShot.AfterCapture += new EventHandler<WindowScreenCaptureEventArgs>(ScreenShot_AfterWindowCapture); } _screenShot.OpenWindowImageCaptureForm(); privatevoid ScreenShot_AfterWindowCapture(object o, WindowScreenCaptureEventArgse) { _image = e.Image; this.Save(_image); }
待改进地方
1,窗体截取时操作比较别扭,需要一个辅助窗体
用鼠标拖拽那个园形图标到目标窗体,然后松开鼠标时,在MouseUp事件里得到目标窗体的句柄。如果没有这个MouseUp事件,我不知道在什么时候,通过什么方式来得到目标窗体的句柄。
2,用方法SetForegroundWindow将选窗体设为最前端时不能马上奇效,权宜之计是调用完这个方法先Sleep 300ms。不然目标窗体的前的窗体也被截屏了,不知道该怎么解决。
对Windows编程熟悉的朋友可以提些建议,谢谢。
参考
编写过程中,借鉴和使用了以下博客或网站的思路或代码,表示感谢。
http://www.cnblogs.com/tuyile006/archive/2007/07/16/815843.html(全屏、区域)
http://www.codeproject.com/KB/dialog/FindWindow.aspx(窗体截取)
http://www.pinvoke.net/(一个很好的wiki)
下载源码(这是csdn的地址,本来想上传到google文档的,可是google文档被和谐了,还需FQ,可惜我放在里面的文档了,哎)