如何獲取桌面截圖


最近工作 中有個需求是抓取桌面截圖, 這里的桌面是指點了“顯示桌面”之后看到的桌面, 截圖內容包括桌面背景和圖標以及任務欄,如下圖: 

 

注意需求是:即使當前其他窗口蓋在我們的桌面上,我們要求抓取到的內容也是這些窗口背后的桌面。

 

思考怎么樣才能在程序運行時,動態抓取該截圖?

大概想了些方法:

(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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM