
文章插圖
有一位名叫小旺的小伙伴,最近和女朋友在追一檔綜藝節目《一年一度喜劇大賽》 。
這檔節目播出以來,形式年輕化、多玩化,劇本也是腦洞頻出、創意無限、極具特色,頗受時下年輕人的追捧 。
其中就有這么一部被主創者自稱為陷阱喜劇的小品《先生請出山》,在播出后突然網絡上就爆火了 。
這不,小旺和他女朋友也著了迷、上了癮,問我能不能把這視頻放到桌面上,這樣不就又可以看又顯得酷了?
有這么讓人癡迷嗎?
我還真有點不信哈,結果當我看了一遍那魔性的舞步和風騷的走位后就再也出不來了!
嘿嘿,沒錯,被成功洗腦的我,現在也時常動不動就想模仿一下那舞步的動作 。
現在大部分年輕人不抽煙不喝酒也就圖點這些樂子了,理解理解!
我和小旺說,不是有不少動態桌面壁紙程序嘛,下載下來用就是了 。
可我得到的回復是,這些軟件不是收費的就是里面夾帶私貨的,都不怎么讓人放心,問有沒有靠譜點的方法 。
也是哈,于是同樣上頭的我研究了好幾天,最終自己動手成功將這魔性舞步視頻當作了動態桌面壁紙!
在本文結尾有自制程序下載,免費安全可靠,不夾帶任何私貨哦~
實驗平臺Windows 10 (默認開啟 Aero)
目標效果可以基本實現在桌面上播放視頻,達到動態桌面的效果 。
與此同時,不妨礙日常的操作,比如桌面圖標的點擊、移動等 。
工具介紹欲善其工,必利其器,除了編程工具外,在正式開始了解原理之前,我們需要先請出“窗口句柄抓取工具”:Microsoft Spy++ 。
它是來自 Vistual Studio的一個實用工具,可以提供系統的進程、線程、窗口及消息的圖形視圖 。

文章插圖
當然如果你對此比較熟悉,也是可以用其他一些窗口句柄查看工具的 。
不過如果你不太清楚什么是窗口句柄,那也沒關系,我簡單給你解釋一哈,你大概了解了解就行 。
首先我們要知道,在系統中窗口(或叫作窗體)是最常用最基本的容器載體,在窗口中會有很多各種各樣不同的控件,它們都是用來操作系統功能或與用戶互動的 。
窗口很重要,那么我們如何管理這些窗口呢?
很簡單,系統會分配給這些窗口一個ID,這個ID就叫作句柄(Handle) 。
這些窗口的句柄就像身份證號碼一樣,當我們想要操作它們的時候,只要告訴系統它們的身份證ID也就是窗口句柄就可以了 。
那么 Spy++可以提供圖形化的參考,讓我們獲知哪個窗口是哪個句柄 。
桌面壁紙原理實際上我們的系統是由很多很多個窗口組成,有的看得見,有的看不見(隱藏或透明),有的看得見但無法直接訪問,而有的即使看不見我們也可以對它進行操作,總之所有的這些窗口互相堆疊最后呈現在我們面前 。
你只要把這些窗口想像成多塊不同的玻璃,就像照鏡子一樣由近及遠、分別多層次地立在了你的面前,有的透明而有的不透明 。
那么對于桌面來說,它也算是一塊玻璃(一個窗口),只是它有些特殊,里面還套著幾個小玻璃(子窗口) 。
因此,大概地了解了窗口的概念,那么我們就可以使用 Spy++來觀察它具體是個啥模樣了 。
桌面窗口本來的模樣如下圖,通過 Spy++來展開當前窗口的句柄樹,就可以非常容易地了解到桌面窗口里面是怎么套娃的 。

文章插圖
最頂上就是桌面窗口的句柄,在它下面還有很多個子窗口 。
其中重點的對于我們有用的就是名字叫作 Program Manager的子窗口,它正是我們苦苦尋找的桌面背景,里面囊括了包含壁紙和圖標的子窗口 。
簡單地說,桌面窗口就如下面這樣的層次 。
|- "Program Manager"Progman // 總體桌面|--- ""SHELLDLL_DefView // 負責顯示桌面圖標|----- "FolderView"SysListView32 // 控制桌面圖標排列順序|------- ""SysHeader32 // 隱藏窗口,功能不詳這些子窗口中的 “” SHELLDLL_DefView就是桌面圖標窗口了 。
簡單說一嘴,引號里是 窗口標題,而后面則是 類名,比如 “Program Manager”就是窗口標題,而 Progman就是類名了 。
知道窗口標題和類名會非常有利于我們查找定位窗口,進而可以方便地對其進行操作 。
直接嵌入 Progman窗口中行嗎根據前面的介紹,我們很容易得出一個結論,既然桌面壁紙和圖標是分別屬于不同的子窗口,那么是不是我們可以將自己的程序窗口插入它們之間,就可以實現在圖標下方顯示呢?
理論想法是沒錯,可經過我的實際測試,非常遺憾根本無法實現這樣的效果!
將程序窗口設定為 Progman的子窗口,雖然它跑到了所有窗口的最后面,但是卻無法在圖標后面顯示 。

文章插圖

文章插圖
那么問題出在哪兒呢?
冒出來個多桌面 WorkerW原來啊,我們使用的是 Windows 10 系統,雖說它默認就支持 Aero效果,但它還有一個多桌面的新功能,你只要按一下 Win + Tab鍵就能看到了 。
而這個多桌面功能會使得桌面窗口產生奇妙的變化,系統會生成多個 WorkerW的窗口出來 。
這個 WorkerW我們可以簡單理解為為了切換桌面的小窗口,只不過現在變出來很多個 。
而跑出來的這么多個 WorkerW窗口中呢,有一個會把原來 Progman下的子窗口給“搶過去”,就像下圖那樣 。

文章插圖
好了,這么一來可壞事了!
我們按照 Progman窗口來找到桌面圖標背景的方法就徹底失效了!
那為啥要搞出來這么多個 WorkerW呢,就不能愉快地使用 Progman嗎?
實際上官方是這么解釋的,為了讓桌面切換呈現平滑過渡的效果,因此設計啟用了多個 WorkerW窗口,否則效果會糟糕到讓你想砸電腦了 。
好吧,道理大家都懂,那接下來怎么整呢?
既然 Progman下的子窗口被“搶過去”了,那是不是我們可以嘗試尋找這個擁有 SHELLDLL_DefView類子窗口的 WorkerW,然后將自己程序的窗口作為子窗口放到它的后面就行了呢?
嘗試將程序窗口嵌入 WorkerW經過我又一番的折騰,發現即使找到了目標 WorkerW,并且將程序窗口放到它在下面還是行不通 。
如下圖,程序窗口雖然跑到了所有窗口的最后面,但卻還是停留在了桌面圖標的前面,效果就跟前面將程序窗口掛在 Progman下面是一樣一樣的 。

文章插圖

文章插圖
這下我就懵了,怎么這也不行,那也不行呢?
實際上這里是有一個套路的,而這個套路著實讓我琢磨了很久很久!
什么套路呢,咱們往下看!
我查閱了網上大量的資料,在不斷的實驗中我發現除了擁有子窗口的 WorkerW之外,其他所有的 WorkerW都是隱藏不可見的 。

文章插圖
而實際有效的做法是,我們需要將程序窗口嵌入到第二個可見非隱藏的 WorkerW之上才行 。
注意它的特點有兩個,第一是排名第二并不含有子窗口,第二是可見非隱藏屬性 。
讓 WorkerW窗口可見并且變透明前面我們說過,按下 Win+Tab鍵可以切換多桌面,當我們這么一切換時,系統就會產生多個 WorkerW窗口用于過渡切換效果 。
所以我們可以用程序模擬按下 Win+Tab鍵 。
不過我嘗試模擬按鍵后,發現有窗口閃動的現象,不是太理想的狀態,于是我找到了網上的資料 。
根據網上資料,Windows 有一個系統保留消息,當我們向 Progman窗口發送 0x052C消息時,桌面就會生成一個透明的 WorkerW窗口,同時會將 Progman的子窗口轉移到這個新生成的 WorkerW之下 。
這也正是我們前面所看到的,子窗口被“搶過去”的效果 。
需要注意的是,這是在 Vista之后的版本才有效,嗯,可以理解為開啟 Aero效果的系統 。
我用 VB代碼很容易就實現了,就像下面這樣 。
' 獲取 Progman 句柄 lngDesktopHwnd = FindWindow("Progman", vbNullString) '然后向Progman發送0x052C使其產生WorkerWSendMessagelngDesktopHwnd,&H52C,0,0遍歷查找目標 WorkerW窗口生成了我們想要的 WorkerW窗口后,我們就要想辦法去找到那個目標窗口,也就是第二個可見的 WorkerW窗口 。
切記,這個 WokerW窗口是可見非隱藏的,并且同時不包含任何子窗口的 。
我的遍歷算法能用但灰常粗糙,你們簡單參考,自己改進哈 。
'獲取桌面句柄lngDesktopHwnd= GetDesktopWindow'獲得第一個 WorkerW 窗口句柄lngWorkerW= FindWindowEx(lngDesktopHwnd, 0, "WorkerW", vbNullString)'定義臨時類名,用于對比查找多個同級的 WorkerW 窗口DimlpClassName As String'遍歷所有 WorkerW 直至找到不擁有 SysListView32 子窗口的那個 WorkerW 為止!DoWhile lngWorkerW > 0IfIsWindowVisible(lngWorkerW) ThenlngShellDll= FindWindowEx(lngWorkerW, 0, "SHELLDLL_DefView", vbNullString)IflngShellDll = 0 ThenExitDoElse'查找下一個同級的類窗體句柄lpClassName= Space(255)DoWhile UCase(Left(lpClassName, 7)) <> UCase("WorkerW")lngWorkerW= GetWindow(lngWorkerW, GW_HWNDNEXT)GetClassNamelngWorkerW, lpClassName, 255LoopEndIfElse'查找下一個同級的類窗體句柄lpClassName= Space(255)DoWhile UCase(Left(lpClassName, 7)) <> UCase("WorkerW")lngWorkerW= GetWindow(lngWorkerW, GW_HWNDNEXT)GetClassNamelngWorkerW, lpClassName, 255LoopEndIfLoop將程序窗口變成目標 WorkerW窗口的子窗口看到沒,就像下圖這樣,我們的程序窗口跑到了第二個可見 WorkerW的下面了 。

文章插圖
參考代碼如下:
' 將程序窗口設定為 WorkerW 的子窗口,WorkerW 成為父窗口 lngOriginalParentHwnd = SetParent(Me.hwnd, lngWorkerW) ' 最后在程序退出時別忘記再變回來 lngTmpHwnd = SetParent(Me.hwnd, lngOriginalParentHwnd)最后,我們看到了這樣的效果,窗口終于跑到了圖標的后面,耶!

文章插圖
效果演示后續還有很多工作需要繼續,比如播放器的操作控制,前景布局等等 。
不過這些繁雜的事不算主要問題,我們只要基本能夠實現桌面動態播放視頻即可 。
就像下面,效果還算可以吧 。
點擊瀏覽,選擇視頻文件 。

文章插圖
先載入視頻,再點擊播放 。

文章插圖
來張動圖展示一下實際效果,可以看到視頻是在圖標后面播放的 。

文章插圖
我搞了兩個版本的程序,對比如下:
- WindowsMediaPlayer:Windows系統自帶無需額外安裝播放器,但可能播放效果差 。
- VLCMediaPlayer:需要單獨安裝 VLC播放器,但播放效果好 。安裝播放器要選擇32位的,同時切記切記務必務必要安裝 ActiveX 插件!!

文章插圖
【全程圖解將視頻設置動態壁紙 怎么把視頻做成動態壁紙】使用方法很簡單,除單獨需要安裝播放器外,下載后只要解壓縮后直接使用就可以了,綠色環保 。
推薦閱讀
- 麻將怎么打初學:麻將基礎入門教程
- 紫光手電筒怎么鑒別翡翠的真假
- 五十鈴玉怎么上盆 五十鈴玉上盆方法
- 誰知道生蠔肉怎么做好吃啊
- ps中怎么將點文字轉換段落文字
- 汽車減壓閥如何調節圖解 有什么原因嗎
- 海參雜蔬小炒怎么做 海參雜蔬小炒的制作方法
- 喜馬拉雅怎么下載到mp3
- 為什么說張騫是冒險家外交家戰將
- 如何做蒸鰈魚 蒸鰈魚做法介紹
