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
  • 相关阅读:
    diary and html 文本颜色编辑,行距和其它编辑总汇
    bash coding to changeNames
    virtualbox ubuntu 网络连接 以及 连接 secureCRT
    linux 学习6 软件包安装
    linux 学习8 权限管理
    vim 使用2 转载 为了打开方便
    ubuntu
    linux 学习15 16 启动管理,备份和恢复
    linux 学习 14 日志管理
    linux 学习 13 系统管理
  • 原文地址:https://www.cnblogs.com/weiym/p/3292459.html
Copyright © 2011-2022 走看看