当前位置: 首页 > news >正文

如何获取桌面截图

最近工作 中有个需求是抓取桌面截图, 这里的桌面是指点了“显示桌面”之后看到的桌面, 截图内容包括桌面背景和图标以及任务栏,如下图: 

 

注意需求是:即使当前其他窗口盖在我们的桌面上,我们要求抓取到的内容也是这些窗口背后的桌面。

 

思考怎么样才能在程序运行时,动态抓取该截图?

大概想了些方法:

(1) 通过Desktop DC, 然后BitBlt
点评: 通过这种方法抓取到的截图是当前桌面的所有窗口,包括其他当前打开显示的窗口 , 这不是我们所期望的。
另外我们也不可能在需要截图时最小化所有窗口, 截完了再还原。

(2)通过注册表获取桌面壁纸保存的地方
点评:获取到该壁纸, 没有图标和任务栏, 也不是我们所期望的。

(3)通过DWM特性来获取
点评: Vista后的Desktop Window Manager(DWM)特性,可以让我们通过DwmRegisterThumbnail,DwmUpdateThumbnailProperties等API实时显示某个窗口的截图。可惜获取到的内容只能显示在我们预定义的窗口里, 但是我们没法获取里面的内容。另外这个特性只有Vista之后才支持, XP系统怎么办?

(4)通过Magnification来获取
点评:我们可以通过系统的放大镜技术, 过滤掉盖在桌面上的其他窗口(MagSetWindowFilterList ),然后通过MagSetImageScalingCallback 拦截内容。该技术的问题一是过滤窗口的个数限制, 另外也只能适用于Vista之后。

 

(5)通过API Hook技术
点评:通过API Hook技术我们可以动态拦截桌面窗口DC的绘画动作,这样就可以拦截或是合成窗口内容了。但是一来这样做比较复杂, 稳定性也很难保证,另外也有杀鸡用牛刀的感觉。

(6)通过PrintWindow技术
点评:PrintWindow API内部通过WM_PRINTCLIENT和WM_PRINT来获取窗口截图, 这个API在XP时代工作的不是很好,但是在Vista之后已经比较稳定了。

我们最后选择通过PrintWindow API来获取桌面截图, 大概过程如下: 
a. 获取桌面窗口(Program Manager)的内容
b. 获取TaskBar窗口的位置和内容
c. 把TaskBar窗口内容和桌面内容合成, 贴在正确的位置

这里说一下要注意的一些问题: 

a . 注意窗口的层次

 

Aero模式下, Program Manager窗口只包含背景图片, 图标列表在WorkerW窗口下:
Basic模式下窗口内容都在Program Manager窗口下:

 

b. 注意多显示器的情况, 多显示器时除了主显示器,其他桌面是没有任务栏的

c. 注意任务栏的位置, 任务栏是可以Dock到任何地方并且以隐藏的,不要hard code在下面了。


d.  XP下对ProgramManager窗口调用PrintWindow会有刷新问题。一直没有好的解决方案, 所以对XP勉强采用第一种DC的方式了。

因此, 我到现在还没有找到完整解决我们这个问题的方法, 不知道大家有没有好的思路?

附上我的测试代码:ScreenSnapshot.rar

转载于:https://www.cnblogs.com/weiym/p/3292459.html

相关文章:

  • matlab练习程序(图像放大/缩小,双线性插值)
  • Python数据类型:双端队列deque-比列表list性能更高的一种数据类型
  • Unity3dUGUI图片循环轮播效果
  • P1379 八数码难题
  • Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的)
  • 深入理解计算机操作系统(三)
  • GrapeCity Demo示例展示:如何用Spread.Sheets来创建应用|附演示文件下载
  • Glovo完成1.15亿欧元C轮融资,成为欧洲相关技术聚合中心
  • json提取嵌套数据
  • abstract 为什么不能与private,static,final一起使用????
  • springboot2整合OAuth2.0认证实例
  • 关于Vue和React区别的一些笔记
  • [Sdoi2010]地精部落
  • samba服务
  • RabbitMQ中各种消息类型如何处理?
  • hexo+github搭建个人博客
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • flask接收请求并推入栈
  • iOS 系统授权开发
  • JDK 6和JDK 7中的substring()方法
  • React Transition Group -- Transition 组件
  • Transformer-XL: Unleashing the Potential of Attention Models
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 简析gRPC client 连接管理
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 用 Swift 编写面向协议的视图
  • PostgreSQL之连接数修改
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • ​什么是bug?bug的源头在哪里?
  • $.ajax()方法详解
  • (1)bark-ml
  • (4.10~4.16)
  • (C语言)二分查找 超详细
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (九十四)函数和二维数组
  • (蓝桥杯每日一题)love
  • (力扣题库)跳跃游戏II(c++)
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (一)UDP基本编程步骤
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转)程序员疫苗:代码注入
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .Family_物联网
  • .NET Framework .NET Core与 .NET 的区别
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • // an array of int
  • @RestControllerAdvice异常统一处理类失效原因
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [<MySQL优化总结>]
  • [BZOJ1053][HAOI2007]反素数ant
  • [C#7] 1.Tuples(元组)
  • [codevs 1288] 埃及分数 [IDdfs 迭代加深搜索 ]