昨天写自动化测试的CASE的时候,碰到一个疑难杂症,调用截图的函数去截取一个Popup窗口,但是总是把背景程序给截下来,Popup窗口就跟看不到一样。本来以为是同步的问题,也就是以为先截图再点击弹出Popup窗口了。后来加了N个Thread.Sleep来测试,发现根本不是因为这个原因,而是截图的函数截不下来这个窗口。
  这个为啥呢,只好把截图的函数代码翻出来看,以前是用这种方式的:
  BitBlt(dcImage, 0, 0, (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, 0);
   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 = 0x1;
  const uint KEYEVENTF_KEYUP = 0x2;
  const byte VK_SNAPSHOT = 0x2C;
  Native.keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, UIntPtr.Zero);
  Native.keybd_event(VK_SNAPSHOT, 0x45, 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.Format24bppRgb);
   Graphics g = Graphics.FromImage(bmpOutput);
   Rectangle destRectangle = new Rectangle(0, 0, (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);
  }
  测试可用,只好先用着了
  不过还有几个问题,先写下来,留待以后解决:
  1. 针对第三种方案,既然可以按PrintScreen键截图,那对应的API是什么,总觉得发键盘消息没有直接调API稳定
  2. 针对WPF截图有没有更好的解决方案

C#中三种截屏方式总结相关推荐

  1. c# 非顶层截屏_C#中三种截屏方式总结

    昨天写自动化测试的CASE的时候,碰到一个疑难杂症,调用截图的函数去截取一个Popup窗口,但是总是把背景程序给截下来,Popup窗口就跟看不到一样.本来以为是同步的问题,也就是以为先截图再点击弹出P ...

  2. Unity3d中的三种截屏方式

    游戏开发项目中会有截屏这样的功能,目前来看,一共有三种方式. 第一种方式:截取某一帧时整个游戏的画面,或者说时全屏截图. 特点:1.不能针对某一个相机的画面进行截图 2.对局部画面截图实现起来不方便, ...

  3. 苹果xr如何截屏_苹果手机自带的三种截屏技巧,你知道几个?现在知道还不迟...

    今年苹果手机发布的新机自发布以来就受到了热烈的追捧,销量一直都处于只增不减的趋势.苹果手机为何如此之火?除了本身自带的IOS系统之外,手机自带很多小技巧,你知道不?今天就来为大家介绍苹果手机中的三种截 ...

  4. 计算机图片怎么截图快捷键,电脑截图快捷键四种截屏方式,笔记本电脑如何截屏截图?...

    电脑截图快捷键四种截屏方式,笔记本电脑如何截屏截图? 网际百科资讯    知识宝库    2020-3-18    43955    0评论 电脑截图快捷键四种截屏方式,笔记本电脑如何截屏截图?给你推 ...

  5. 华为手机的7种截屏方式

    华为手机作为国产手机的招牌之一,深受很多用户的喜爱,使用手机的过程中也难免少不了截图,而华为手机中却有多种方法,方便你在各种情况下截图,你用过几种呢? 1.传统截屏方式 说到我们最传统的一种截图方式相 ...

  6. android 截屏 效率,手机知识大科普!效率神器!华为手机这几种截屏方式你知道吗?...

    手机知识大科普!效率神器!华为手机这几种截屏方式你知道吗? 2020-03-06 19:44:35 0点赞 3收藏 0评论 如今手机已经成为了我们最为亲密的伙伴,不仅应付我们的日常生活,就连很多办公也 ...

  7. 华为手机你知道几种截屏方式呢?其实有7种,看看你用过几个?

    华为手机作为国产手机的招牌之一,深受很多用户的喜爱,使用手机的过程中也难免少不了截图,而华为手机中却有多种方法,方便你在各种情况下截图,你用过几种呢? 1.传统截屏方式 说到我们最传统的一种截图方式相 ...

  8. 小米手机截屏方式还能这么玩?7种截屏方式任你选

    先来做一个调查,你们都用过几种截屏方式? 小米手机系统在几次重大更新后,竟然有7种截屏方式.不知道小米手机用户们,你们都用过几种呢?下面我们就一起来看看吧! 一.三指下滑触发截屏 只要三只手机同时滑动 ...

  9. 荣耀android手机怎么截图,荣耀30怎么截屏?荣耀30三种截屏方法

    从苹果手机换荣耀30手机,但是不会截屏,想要截屏怎么办呢? 荣耀30三种截屏方法 荣耀30是华为旗下荣耀的一款智能手机,于2020年4月15日发布.不过由苹果转过来的可以通过下面的方法截图. 使用组合 ...

最新文章

  1. scss里的符号的用法
  2. linux 中 svn 服务器搭建 重启
  3. 互联网日报 | 阿里国内消费者已接近10亿;联想布局半导体赛道;我国5G用户超过6千万户...
  4. Codeweavers的丰田模式
  5. CCF NOI1076 进制转换
  6. Tomcat报错:The required Server component failed to start so Tomcat is unable to start
  7. 安川机器人梯形图指令(三)
  8. 桥连模式,模板模式的改进
  9. IntelliJ IDEA插件的Jrebel激活踩坑【内网离线使用】
  10. 过QQ游戏大厅的SX保护
  11. java+字节码工具64位_javassist:字节码编辑器工具
  12. win10系统激活提示无法连接到你组织的激活服务器如何解决
  13. 做好拼多多的几个小技巧-拼多多出评技巧
  14. 习练真气运行法必须从调整呼吸入手
  15. html中怎么设置input的背景颜色,css里我们选中一个div里的一个input设置背景色
  16. word插入Java代码
  17. android studio 配置+安装
  18. 为什么说 Flutter 可能不是下一件大事?
  19. 抑郁男子怀揣妻女照片坚强生存25天
  20. Java常用时间计算

热门文章

  1. C++全局变量和局部变量有什么区别
  2. 计算机辅助测试英语缩写,“CAT”是“Computer-Aided Testing”的缩写,意思是“计算机辅助测试”...
  3. 细粒度图像分类_支付宝AI大幅提升细粒度图像分类识别精度:一眼看穿万物细微差异...
  4. 华睿相机sdk 开发_告别翻转腾挪,读码一步到位丨华睿科技六面读码系统
  5. 3.TF-IDF算法介绍、应用、NLTK实现TF-IDF算法、Sklearn实现TF-IDF算法、算法的不足、算法改进
  6. VMware虚拟机启动后出现黑屏,不能显示界面,无论安装的是ubuntu、kali还是centos
  7. Spring+mongodb集群集成(吐血教程) 转自:http://blog.csdn.net/qq_16497617/article/details/52817335
  8. Nginx安装,Nginx静态缓存,Nginx Gzip压缩,Nginx负载均衡,Nginx方向代理,Nginx+Tomcat+Redis做session共享
  9. 19_Android中图片处理原理篇,关于人脸识别网站,图片加载到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写
  10. 微信回调接口java返回true_java 微信支付异步回调接口