知识大全 C#中三种截屏方式小结
Posted 知
篇首语:从来好事天生俭,自古瓜儿苦后甜。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 C#中三种截屏方式小结相关的知识,希望对你有一定的参考价值。
C#中三种截屏方式小结 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
昨天写自动化测试的CASE的时候 碰到一个疑难杂症 调用截图的函数去截取一个Popup窗口 但是总是把背景程序给截下来 Popup窗口就跟看不到一样 本来以为是同步的问题 也就是以为先截图再点击弹出Popup窗口了 后来加了N个Thread Sleep来测试 发现根本不是因为这个原因 而是截图的函数截不下来这个窗口 这个为啥呢 只好把截图的函数代码翻出来看 以前是用这种方式的 BitBlt(dcImage (int)(rect Width) (int)(rect Height) dcScreen (int)(rect Left) (int)(rect Top) TernaryRasterOperations SRCCOPY) 凭直觉感觉应该是因为这种通过DC的方式对WPF程序支持有问题 但是又觉得奇怪就是截取其它的WPF组件和窗口都没有问题 偏偏Popup窗口不行 前些天听说另外一种截屏的方法 这种方法连被遮挡的窗口都可以截 于是就Google一大把 找打了PrintWindow函数 于是就有了第二种解决方案 代码如下 IntPtr hdc = Native GetWindowDC(this Handle);if (hdc != IntPtr Zero) IntPtr hdcMem = Native CreateCompatibleDC(hdc); if (hdcMem != IntPtr Zero) IntPtr hbitmap = Native CreateCompatibleBitmap(hdc (int)(Rect Width) (int)(Rect Height)); if (hbitmap != IntPtr Zero) Native SelectObject(hdcMem hbitmap); Native PrintWindow(this Handle hdcMem );
Native DeleteObject(hbitmap); Bitmap bmp = Bitmap FromHbitmap(hbitmap); bmp Save(sPath); Native DeleteObject(hdcMem); Native ReleaseDC(this Handle hdc);
就是拿到窗口的句柄 通过PrintWindow API来截取窗口
但是更让人气愤的事情出现了 截出来的窗口中 只要是用到WPF组件的地方 全部是黑块儿 只有MFC的窗口框架和按钮可以正常被截取
于是乎 就无奈的继续分析这个问题 我记得WPF是没有走GDI 而是通过Directx渲染的 那就是说DC的方式和PrintWindow的方式都不靠谱 但是截Directx的貌似还比较复杂
突然想起来 平常报bug的时候都是按PrintScreen 然后再处理一下的 那应该PrintScreen按键是管用的 看来只能曲线救国了 但是那样就得走剪切板了 貌似会破坏剪切板的数据 不过如果我在截取前保存一下数据 在截取后再恢复一下剪切板数据 那就没有问题了
于是就有了第三种解决方案(暂时还没有加恢复剪切板数据的代码)
const uint KEYEVENTF_EXTENDEDKEY = x ;const uint KEYEVENTF_KEYUP = x ;const byte VK_SNAPSHOT = x C;Native keybd_event(VK_SNAPSHOT x KEYEVENTF_EXTENDEDKEY UIntPtr Zero);Native keybd_event(VK_SNAPSHOT x KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP UIntPtr Zero);
IDataObject iObj = Clipboard GetDataObject();if (iObj GetDataPresent(DataFormats Bitmap true)) Bitmap bmpScreen = iObj GetData(DataFormats Bitmap true) as Bitmap; Bitmap bmpOutput = new Bitmap((int)this Rect Width (int)this Rect Height System Drawing Imaging PixelFormat Format bppRgb); Graphics g = Graphics FromImage(bmpOutput); Rectangle destRectangle = new Rectangle( (int)this Rect Width (int)this Rect Height); g DrawImage(bmpScreen destRectangle (int)this Rect X (int)this Rect Y (int)this Rect Width
(int)this Rect Height GraphicsUnit Pixel); bmpOutput Save(sPath System Drawing Imaging ImageFormat Bmp);
测试可用 只好先用着了
不过还有几个问题 先写下来 留待以后解决
针对第三种方案 既然可以按PrintScreen键截图 那对应的API是什么 总觉得发键盘消息没有直接调API稳定
cha138/Article/program/net/201311/13188相关参考
Delphi中三种延时方法及其定时精度分析 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!在Delp
JavaSwing中三种事件处理方法的比较 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Swi
JavaSwing中三种事件处理方法之比较 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Swi
知识大全 Java Web开发Tomcat中三种部署项目的方法
JavaWeb开发Tomcat中三种部署项目的方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
VisualC#程序设计技巧小结 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 获取文件的版本信
技术分享小结Hibernate的查询方式 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! get(
C#里面比较时间大小三种方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 比较时间大小的实验s
C#中启动进程的三种方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!启动子进程不等待子进程结束
知识大全 C#中datatabel导出excel(三种方法)
C#中datatabel导出excel(三种方法) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
C#中using的三种使用方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!引入命名空间using