C#中三种截屏方式总结
昨天写自动化测试的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#中三种截屏方式总结相关推荐
- c# 非顶层截屏_C#中三种截屏方式总结
昨天写自动化测试的CASE的时候,碰到一个疑难杂症,调用截图的函数去截取一个Popup窗口,但是总是把背景程序给截下来,Popup窗口就跟看不到一样.本来以为是同步的问题,也就是以为先截图再点击弹出P ...
- Unity3d中的三种截屏方式
游戏开发项目中会有截屏这样的功能,目前来看,一共有三种方式. 第一种方式:截取某一帧时整个游戏的画面,或者说时全屏截图. 特点:1.不能针对某一个相机的画面进行截图 2.对局部画面截图实现起来不方便, ...
- 苹果xr如何截屏_苹果手机自带的三种截屏技巧,你知道几个?现在知道还不迟...
今年苹果手机发布的新机自发布以来就受到了热烈的追捧,销量一直都处于只增不减的趋势.苹果手机为何如此之火?除了本身自带的IOS系统之外,手机自带很多小技巧,你知道不?今天就来为大家介绍苹果手机中的三种截 ...
- 计算机图片怎么截图快捷键,电脑截图快捷键四种截屏方式,笔记本电脑如何截屏截图?...
电脑截图快捷键四种截屏方式,笔记本电脑如何截屏截图? 网际百科资讯 知识宝库 2020-3-18 43955 0评论 电脑截图快捷键四种截屏方式,笔记本电脑如何截屏截图?给你推 ...
- 华为手机的7种截屏方式
华为手机作为国产手机的招牌之一,深受很多用户的喜爱,使用手机的过程中也难免少不了截图,而华为手机中却有多种方法,方便你在各种情况下截图,你用过几种呢? 1.传统截屏方式 说到我们最传统的一种截图方式相 ...
- android 截屏 效率,手机知识大科普!效率神器!华为手机这几种截屏方式你知道吗?...
手机知识大科普!效率神器!华为手机这几种截屏方式你知道吗? 2020-03-06 19:44:35 0点赞 3收藏 0评论 如今手机已经成为了我们最为亲密的伙伴,不仅应付我们的日常生活,就连很多办公也 ...
- 华为手机你知道几种截屏方式呢?其实有7种,看看你用过几个?
华为手机作为国产手机的招牌之一,深受很多用户的喜爱,使用手机的过程中也难免少不了截图,而华为手机中却有多种方法,方便你在各种情况下截图,你用过几种呢? 1.传统截屏方式 说到我们最传统的一种截图方式相 ...
- 小米手机截屏方式还能这么玩?7种截屏方式任你选
先来做一个调查,你们都用过几种截屏方式? 小米手机系统在几次重大更新后,竟然有7种截屏方式.不知道小米手机用户们,你们都用过几种呢?下面我们就一起来看看吧! 一.三指下滑触发截屏 只要三只手机同时滑动 ...
- 荣耀android手机怎么截图,荣耀30怎么截屏?荣耀30三种截屏方法
从苹果手机换荣耀30手机,但是不会截屏,想要截屏怎么办呢? 荣耀30三种截屏方法 荣耀30是华为旗下荣耀的一款智能手机,于2020年4月15日发布.不过由苹果转过来的可以通过下面的方法截图. 使用组合 ...
最新文章
- scss里的符号的用法
- linux 中 svn 服务器搭建 重启
- 互联网日报 | 阿里国内消费者已接近10亿;联想布局半导体赛道;我国5G用户超过6千万户...
- Codeweavers的丰田模式
- CCF NOI1076 进制转换
- Tomcat报错:The required Server component failed to start so Tomcat is unable to start
- 安川机器人梯形图指令(三)
- 桥连模式,模板模式的改进
- IntelliJ IDEA插件的Jrebel激活踩坑【内网离线使用】
- 过QQ游戏大厅的SX保护
- java+字节码工具64位_javassist:字节码编辑器工具
- win10系统激活提示无法连接到你组织的激活服务器如何解决
- 做好拼多多的几个小技巧-拼多多出评技巧
- 习练真气运行法必须从调整呼吸入手
- html中怎么设置input的背景颜色,css里我们选中一个div里的一个input设置背景色
- word插入Java代码
- android studio 配置+安装
- 为什么说 Flutter 可能不是下一件大事?
- 抑郁男子怀揣妻女照片坚强生存25天
- Java常用时间计算
热门文章
- C++全局变量和局部变量有什么区别
- 计算机辅助测试英语缩写,“CAT”是“Computer-Aided Testing”的缩写,意思是“计算机辅助测试”...
- 细粒度图像分类_支付宝AI大幅提升细粒度图像分类识别精度:一眼看穿万物细微差异...
- 华睿相机sdk 开发_告别翻转腾挪,读码一步到位丨华睿科技六面读码系统
- 3.TF-IDF算法介绍、应用、NLTK实现TF-IDF算法、Sklearn实现TF-IDF算法、算法的不足、算法改进
- VMware虚拟机启动后出现黑屏,不能显示界面,无论安装的是ubuntu、kali还是centos
- Spring+mongodb集群集成(吐血教程) 转自:http://blog.csdn.net/qq_16497617/article/details/52817335
- Nginx安装,Nginx静态缓存,Nginx Gzip压缩,Nginx负载均衡,Nginx方向代理,Nginx+Tomcat+Redis做session共享
- 19_Android中图片处理原理篇,关于人脸识别网站,图片加载到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写
- 微信回调接口java返回true_java 微信支付异步回调接口