将《先生请出山》放到桌面上,聊聊如何将视频做成动态壁纸

网管小贾 / sysadm.cc

网管小贾 / sysadm.cc

有一位名叫小旺的小伙伴,最近和女朋友在追一档综艺节目《一年一度喜剧大赛》。

这档节目播出以来,形式年轻化、多玩化,剧本也是脑洞频出、创意无限、极具特色,颇受时下年轻人的追捧。

其中就有这么一部被主创者自称为陷阱喜剧的小品《先生请出山》,在播出后突然网络上就爆火了。

这不,小旺和他女朋友也着了迷、上了瘾,问我能不能把这视频放到桌面上,这样不就又可以看又显得酷了?


有这么让人痴迷吗?

我还真有点不信哈,结果当我看了一遍那魔性的舞步和风骚的走位后就再也出不来了!

嘿嘿,没错,被成功洗脑的我,现在也时常动不动就想模仿一下那舞步的动作。

现在大部分年轻人不抽烟不喝酒也就图点这些乐子了,理解理解!

我和小旺说,不是有不少动态桌面壁纸程序嘛,下载下来用就是了。

可我得到的回复是,这些软件不是收费的就是里面夹带私货的,都不怎么让人放心,问有没有靠谱点的方法。

也是哈,于是同样上头的我研究了好几天,最终自己动手成功将这魔性舞步视频当作了动态桌面壁纸!


在本文结尾有自制程序下载,免费安全可靠,不夹带任何私货哦~


实验平台

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 使其产生 WorkerW
SendMessage lngDesktopHwnd, &H52C, 0, 0

遍历查找目标 WorkerW 窗口

生成了我们想要的 WorkerW 窗口后,我们就要想办法去找到那个目标窗口,也就是第二个可见的 WorkerW 窗口。

切记,这个 WokerW 窗口是可见非隐藏的,并且同时不包含任何子窗口的。

我的遍历算法能用但灰常粗糙,你们简单参考,自己改进哈。


' 获取桌面句柄
lngDesktopHwnd = GetDesktopWindow

' 获得第一个 WorkerW 窗口句柄
lngWorkerW = FindWindowEx(lngDesktopHwnd, 0, "WorkerW", vbNullString)

' 定义临时类名,用于对比查找多个同级的 WorkerW 窗口
Dim lpClassName As String

' 遍历所有 WorkerW 直至找到不拥有 SysListView32 子窗口的那个 WorkerW 为止!
Do While lngWorkerW > 0

	If IsWindowVisible(lngWorkerW) Then

		lngShellDll = FindWindowEx(lngWorkerW, 0, "SHELLDLL_DefView", vbNullString)

		If lngShellDll = 0 Then
			Exit Do
		Else
		
            ' 查找下一个同级的类窗体句柄
            lpClassName = Space(255)
            Do While UCase(Left(lpClassName, 7)) <> UCase("WorkerW")
                lngWorkerW = GetWindow(lngWorkerW, GW_HWNDNEXT)
                GetClassName lngWorkerW, lpClassName, 255
            Loop
    	End If

	Else
	
        ' 查找下一个同级的类窗体句柄
        lpClassName = Space(255)
        Do While UCase(Left(lpClassName, 7)) <> UCase("WorkerW")
            lngWorkerW = GetWindow(lngWorkerW, GW_HWNDNEXT)
            GetClassName lngWorkerW, lpClassName, 255
        Loop
    End If

Loop

将程序窗口变成目标 WorkerW 窗口的子窗口

看到没,就像下图这样,我们的程序窗口跑到了第二个可见 WorkerW 的下面了。

在这里插入图片描述


参考代码如下:

' 将程序窗口设定为 WorkerW 的子窗口,WorkerW 成为父窗口
lngOriginalParentHwnd = SetParent(Me.hwnd, lngWorkerW)
    
' 最后在程序退出时别忘记再变回来
lngTmpHwnd = SetParent(Me.hwnd, lngOriginalParentHwnd)

最后,我们看到了这样的效果,窗口终于跑到了图标的后面,耶!

在这里插入图片描述


效果演示

后续还有很多工作需要继续,比如播放器的操作控制,前景布局等等。

不过这些繁杂的事不算主要问题,我们只要基本能够实现桌面动态播放视频即可。

就像下面,效果还算可以吧。


点击浏览,选择视频文件。

在这里插入图片描述


先载入视频,再点击播放。

在这里插入图片描述


来张动图展示一下实际效果,可以看到视频是在图标后面播放的。

在这里插入图片描述


我搞了两个版本的程序,对比如下:

  • WindowsMediaPlayerWindows 系统自带无需额外安装播放器,但可能播放效果差。

  • VLCMediaPlayer:需要单独安装 VLC 播放器,但播放效果好。

    安装播放器要选择32位的,同时切记切记务必务必要安装 ActiveX 插件 !!

    在这里插入图片描述


使用方法很简单,除单独需要安装播放器外,下载后只要解压缩后直接使用就可以了,绿色环保。


网管小贾的MP4动态壁纸程序(WindowsMediaPlayer).7z (106K)

下载链接:https://pan.baidu.com/s/1HYATSyA3H2YNPivAu2i6aw

提取码:<关注公众号,发送 000903 或 先生请出山>


网管小贾的MP4动态壁纸程序(VLCMediaPlayer).7z (106K)

VLC 安装包较大,此压缩包不含 VLC 安装包,请到下面官网链接下载。

下载链接:https://pan.baidu.com/s/1uiSTHTdujRD62sPuj7M03A

提取码:<关注公众号,发送 000903 或 先生请出山>


VLC Media Player(vlc-3.0.16-win32).exe (40M)

当前最新版本 3.0.16 ,切记安装 32 位。

下载链接:https://www.videolan.org/


《先生请出山》魔性舞步演示视频小片段

下载链接:https://pan.baidu.com/s/1PgIkBv–E3A5Dwuwt9VWvA

提取码:<关注公众号,发送 000903 或 先生请出山>


写在最后

前面啰嗦了一大堆,窗口已经实现在桌面图标后面显示了,之后的工作也就此继续展开。

虽然在窗口上加上个播放器,然后再给它一些播放时的操作控制功能看似简单,但起先我为了节约时间就把系统默认自带的 Windows Media Player 直接拿来用了,自然有时候它的播放效果并不是很理想,特别是对于要求高的小伙伴。

当然以后有时间的话,我是会改进这一问题,使用 libVLC 来做为播放引擎。

(PS:目前已经初步补上了,下载链接前面有~)


除播放器外,前景布局效果也是挺有挑战性的,比如在桌面图标的后面和视频的前面挂个 Logo 或是时钟啥的。

当然这是以后我有空有闲的事了。

在这里需要向小伙伴们声明一下,由于我也是个小白,查找资料连带测试花了我不少时间,因此做出来的最终效果可能无法和那些商业软件相比,请小伙伴多多包涵。


好了,至少对我来说还算满意,小旺同学也试用OK,和女朋友感情升温,关系也更进了一步,也算我成就了一桩好事啊!

如果你们喜欢,或是有此需要,尽管拿去拿去别客气!

但是哈,别忘记关注、点赞外加转发哦!

祝小伙伴们新年心想事成,一切顺遂,么么哒~

网管小贾 / sysadm.cc


猜你喜欢

转载自blog.csdn.net/kydd2008/article/details/122467004