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按键是管用的,看来只能曲线救国了。但是那样就得走剪切板了,貌似会破坏剪切板的数据,不过如果我在截取前保存一下数据,在截取后再恢复一下剪切板数据,那就没有问题了。

时间: 2024-09-11 03:34:27

C#中三种截屏方式总结的相关文章

【SSH系列】深入浅出spring IOC中三种依赖注入方式

spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和依赖查找,依赖什么?为什么需要依赖?注入什么?控制什么?依赖注入和控制反转是一样的概念吗?接触新的知识,小编的脑袋中全是大大的问号,不过没有关系,今天这篇博文,小编主要来简单的介绍一下在spring IOC中依赖注入的方法. 依赖注入和控制反转,目的是为了使类与类之间解耦合,提高系统的可扩展性和可维护性.我们可以从以下几个方面理解: a.参与者都

MySQL中三种关联查询方式的简单比较_Mysql

看看下面三个关联查询的 SQL 语句有何区别?   SELECT * FROM film JOIN film_actor ON (film.film_id = film_actor.film_id) SELECT * FROM film JOIN film_actor USING (film_id) SELECT * FROM film, film_actor WHERE film.film_id = film_actor.film_id 最大的不同更多是语法糖,但有一些有意思的东西值得关注.

android中Webview实现截屏三种方式小结

本人最近学习了android中Webview实现截屏三种方式,下面我来记录一下,有需要了解的朋友可参考.希望此文章对各位有所帮助. 第一种方式 通过调用webview.capturePicture(),得到一个picture对象,根据图像的宽和高创建一个Bitmap,再创建一个canvas,绑定bitmap,最后用picture去绘制. //获取Picture对象 Picture picture = wv_capture.capturePicture(); //得到图片的宽和高(没有reflec

深入浅析JavaScript中对事件的三种监听方式_javascript技巧

事件(Event)是JavaScript应用跳动的心脏,也是把所有东西粘在一起的胶水,当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了. 第一种监听方式,也是最普遍使用的方式,是直接在代码上加载事件,产生效果: <table> <tr onmouseover='this.style.backgroundColor="red"' onmouseout='this.style.backgroundColor=""'><td>

XP系统的三种锁屏方法及其优缺点介绍

XP系统的三种锁屏方法及其优缺点介绍   1.不使用欢迎屏幕(此时亦不能使用快速用户切换). 2.仅使用欢迎屏幕. 3.既使用欢迎屏幕,又使用快速用户切换. 当安装完Windows XP后,默认的设置是3. 下面根据"用户登录或注销的方式"设置的不同,分别介绍其锁屏的方法. 设置1:同Windows 2000和Windows NT4.0 使用方法完全相同,界面也类似. 优点:是真正的"锁定计算机",在你锁定了计算机后,其他用户(管理员除外)就不能使用此计算机. 缺点

三星S6怎么截屏 三星S6两种截屏方法

方法一,Android系统自带截屏方式 同时按住手机的[电源键]+[HOME键]两秒,就可以完成截屏了.(如下图) 方法二,掌擦截图 点击[应用程序]-[设定]-[我的设备]-[动作与手势]-[手掌动作]开户它[手掌动作]-[截取屏幕]选项开启. 设置后,当您想截图时,直接用手的侧面从右至左(从左至右)划过屏幕即可截图. 上面两种截图文件全部都保存在三星S6手机的 "应用程序"-我的文件-所有文件-Device storage-Pictures-Screenshots目录中了. 总结,

oppo r7s手机4种截屏截图方法

oppo r7s截图方法教程 方法一:最简单快捷的截图方式,进入截图界面然后按下"电源键"加"音量减键",一起按住即可轻松截屏. 方法二:手机自带的功能,一在进入到oppor7s手机的界面我们点击"设置"--"常规"--"手势体感"--将"三指截屏"开启,在屏幕任意界面位置三指向上或者向下滑动即可截屏. 方法三:长截屏方法,这种方法和方法一有一点像了,我们只要在截图界面 电源键加减音键一

Android实现截屏方式整理(总结)

本文介绍了Android 实现截屏方式整理,分享给大家.希望对大家有帮助 可能的需求: 截自己的屏 截所有的屏 带导航栏截屏 不带导航栏截屏 截屏并编辑选取一部分 自动截取某个空间或者布局 截取长图 在后台去截屏 1.只截取自己应用内部界面 1.1 截取除了导航栏之外的屏幕 View dView = getWindow().getDecorView(); dView.setDrawingCacheEnabled(true); dView.buildDrawingCache(); Bitmap

Android中3种全屏方法及3种去掉标题栏的方法

这篇文章主要介绍了Android中3种全屏方法及3种去掉标题栏的方法,二个问题各给出了3种解决方法,并给出实例代码,需要的朋友可以参考下     一.去掉标题栏的方法 第一种:入门的时候经常使用的一种方法 代码如下: requestWindowFeature(Window.FEATURE_NO_TITLE); //去掉标题栏注意这句一定要写在setContentView()方法的前面,不然会报错的 第二种:在AndroidManifest.xml文件中定义 代码如下: <application