如何实现一个 windows 桌面动态壁纸 随笔 第1张如何实现一个 windows 桌面动态壁纸 随笔 第2张

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

更新:

  • 2018/08/31 WS_MOUSE_LL 钩子,实现底层壁纸交互效果。

一、介绍

国内玩家第一次看到动态壁纸,都是出于一款来自 Wallpaper Engine 的 Steam 程序。它允许将视频、窗口小部件、甚至是有一定交互的网页放置到桌面最下方,2016 年初,被b站up主们广泛传播,被大家熟知。

如何实现一个 windows 桌面动态壁纸 随笔 第3张如何实现一个 windows 桌面动态壁纸 随笔 第4张

Miku

 

原理其实并不难,然而...

前端程序员A:这个 WebGL 特效我能吹一年,赶紧做成壁纸,...什么要写C++的?不可能的,一辈子都不会写中级语言的。

c/c++程序员B:靠...,这帮刁民又想骗我做设计。

 

Wallpaper Engine 成功的原因是赢在了稳定性、兼容性和玩家老哥组成的丰富的创意工坊。

 

这种壁纸小程序,Github上还没有Python 的实现,但是核心方法仅仅是操作win32api,python完全可以实现,你听说过pywin32吗。。。看完这篇教程,你可以做第一个。

 

假如你不想了解原理,前端程序员可以直接移步第三步。

二、实现原理

本篇文章意在讲解原理,你可以把它当成一个前端程序员的小工具,可能无法达到商用程度。

  • 监听底端事件,容易造成 windows消息堵塞
  • 占用大量内存(等于是多挂起了一个浏览器)
  • 无法兼容关闭aero的win7 和 win8

 

原理:windows 最底层的窗体 Program Manage (如图所示),想要你的窗体出现在桌面icon后面,只需要把自己的窗体作为 Program Manage 的子窗体,然后隐藏原先的壁纸层就可以了,win10 你可以选择在原先壁纸之上和icon之下的位置(可以省略隐藏原壁纸),但这种是兼容win7和win10的做法。

欢迎光临程序代写小店https://item.taobao.com/item.htm?spm=a230r.1.14.59.255028c3ALNkZ0&id=586797758241&ns=1&abbucket=15#detail

matlab程序代写C++代做C语言java安卓app设计python网站php代码 一流985硕博团队为您服务

可直接联系客服QQ交代需求:953586085

你可以使用 Visual Studio的 Spy++来查看 Window的窗体。

如何实现一个 windows 桌面动态壁纸 随笔 第5张如何实现一个 windows 桌面动态壁纸 随笔 第6张

 

我们现在知道了,workerw 作为我们的图标和壁纸(灰色的workerw,因为已经隐藏)的父窗体出现在底层窗体之上。

博主你又骗我,为什么我的电脑上,只有一个WorkerW,图标和壁纸都黏在一起了?

如何实现一个 windows 桌面动态壁纸 随笔 第7张如何实现一个 windows 桌面动态壁纸 随笔 第8张

 

这是一条神奇的 message,是 windows 为了解决切换壁纸的时候丑陋的闪切而创建的(未公开消息),它使得更换壁纸的时候有一个平滑的过渡但又不影响绘制壁纸,它会分离创建两个 WorkerW,我们只需要隐藏没有 SysListView (用于存放桌面 icon 的窗体) 的那一个就可以了。

如何实现一个 windows 桌面动态壁纸 随笔 第9张如何实现一个 windows 桌面动态壁纸 随笔 第10张

 

那么接下来,你需要做的就是用winapi遍历找到窗体,完成任务了:

#include <utils.h>

HWND _workerw = nullptr;

inline BOOL CALLBACK EnumWindowsProc(_In_ HWND tophandle, _In_ LPARAM topparamhandle)
{
    HWND defview = FindWindowEx(tophandle, 0, L"SHELLDLL_DefView", nullptr);
    if (defview != nullptr)
    {
        _workerw = FindWindowEx(0, tophandle, L"WorkerW", 0);
    }
    return true;
}

HWND Utils::GetWorkerW(){
    int result;
    HWND windowHandle = FindWindow(L"Progman", nullptr);
    SendMessageTimeout(windowHandle, 0x052c, 0 ,0, SMTO_NORMAL, 0x3e8,(PDWORD_PTR)&result);
    EnumWindows(EnumWindowsProc,(LPARAM)nullptr);
    ShowWindow(_workerw,SW_HIDE);
    return windowHandle;
}
如何实现一个 windows 桌面动态壁纸 随笔 第11张

你的窗体需要:

SetParent((HWND)view->winId(),Utils::GetWorkerW());
如何实现一个 windows 桌面动态壁纸 随笔 第12张

还是不明白?

github 链接奉上:ThomasHuai/Wallpaper

 

为什么 win8 和 win7(关闭areo)不能使用这种方法?

如何实现一个 windows 桌面动态壁纸 随笔 第13张如何实现一个 windows 桌面动态壁纸 随笔 第14张

这种情况下,SysListView 被直接当做了 Program Manager 的子窗体,但是这并不是关键,关键是壁纸和图标融合在了一起,无论你把你的窗体放到上面位置,都不可能出现在原壁纸与icon 中间。

 

三、然而这是一个前端 Demo

 

发布版下载地址:ThomasHuai/Wallpaper

 

可以使用以下两种方式设置壁纸:

  • 本地路径
  • 线上URL(可以copy别人的demo地址)

假如你是双屏的可以设置三种屏幕布局:

  • 主屏
  • 侧屏
  • 平铺(延展至多屏)

 

2018/08/31更新:

使用 WS_MOUSE_LL 钩子,实现底层壁纸交互效果。

 

壁纸程序使用的是QT的 WebEngine(5.8),chrome 内核浏览器,相当于在屏幕后面挂起了一个浏览器,也就是说 chrome 能做的,它都可以实现,css3动画,webGL,背景音频 + 音频可视化等,自带了一个粒子动画的demo。

如何实现一个 windows 桌面动态壁纸 随笔 第15张如何实现一个 windows 桌面动态壁纸 随笔 第16张

粒子动画(自带)

 

 

如何实现一个 windows 桌面动态壁纸 随笔 第17张如何实现一个 windows 桌面动态壁纸 随笔 第18张

three.js

 

 

如何实现一个 windows 桌面动态壁纸 随笔 第19张如何实现一个 windows 桌面动态壁纸 随笔 第20张

three.js

如何实现一个 windows 桌面动态壁纸 随笔 第21张如何实现一个 windows 桌面动态壁纸 随笔 第22张

水中泡泡(自带)

如何实现一个 windows 桌面动态壁纸 随笔 第23张如何实现一个 windows 桌面动态壁纸 随笔 第24张

涟漪效果(自带)

 

多屏效果:

 

桌面动态壁纸,藤蔓无限延展

 

 

Github 项目链接:

NoisyWinds/Wallpaper​github.com如何实现一个 windows 桌面动态壁纸 随笔 第25张如何实现一个 windows 桌面动态壁纸 随笔 第26张

参考资料:

https://www.codeproject.com/Articles/856020/Draw-Behind-Desktop-Icons-in-Windows-plus​www.codeproject.com

 

 

欢迎点赞评论,关注后续文章,一起交流学习。

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄