如何獲取桌面截圖

最近工做 中有個需求是抓取桌面截圖, 這裏的桌面是指點了「顯示桌面」以後看到的桌面, 截圖內容包括桌面背景和圖標以及任務欄,以下圖: 

 

注意需求是:即便當前其餘窗口蓋在咱們的桌面上,咱們要求抓取到的內容也是這些窗口背後的桌面。windows

 

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

大概想了些方法:

(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
相關文章
相關標籤/搜索