zoukankan      html  css  js  c++  java
  • 如何获取桌面截图

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

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

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

    大概想了些方法:

    (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
  • 相关阅读:
    Js--小笔记
    Android Gson解析
    java格式化数字、货币、金钱
    关于Edittext默认弹出软键盘为数字键
    生日星座自动匹配
    ANDROID STUDIO系列教程六--GRADLE多渠道打包
    框架,简化了代码的同时,也让我们慢慢变蠢
    Android开发实现高德地图定位
    onNewIntent调用时机
    EditText输入手机号自动带空格
  • 原文地址:https://www.cnblogs.com/weiym/p/3292459.html
Copyright © 2011-2022 走看看