编写Windows动态壁纸(关于Windows10桌面的了解)(一)

news/2024/11/7 23:45:27/

一、杂言

作为一个编程爱好者,同时,也作为一个宅。电脑几乎是每天都必须碰上几个小时的。对于Win10的桌面,自己的心中多多少少也希望能好看一点。市面上有很多桌面美化软件,但基本都不符合我的心意,有美化的没整理功能,有整理功能的没美化。秉承着对电脑的爱好之心,还是自己动手,丰衣足食吧(无奈脸)。

(然并卵,虽然市面上有这么多的桌面整理和美化软件,而能查到得的资料却少到可怜。也许国外比较多。)

 

二、正题

先来了解一下win10的桌面底层。

用按键精灵的抓抓或者是spy++观察一下桌面上的窗口。

在这幅图中,SysListView32和SHELLDLL_DefView是管理和显示桌面图标的。Progman是显示出来的总桌面,也是总程序,如果你向Progman窗口发送一个WM_CLOSE消息,Windows就会提醒你是否要关机。

我们先试着单独隐藏一下Progman窗口。

然后,整个窗口就黑了。这说明,Progman的确是总桌面。

我们再试着单独隐藏一下SHELLDLL_DefView窗口。

桌面的图标就不见了,这说明SHELLDLL_DefView是负责显示桌面图标的。

而关于SysListView32,这个窗口是控制桌面图标的排列顺序的,如果要加上桌面整理功能的话,可能要用得上它。

通过以上的演示,我们发现,在Windows中,桌面壁纸的显示和图标的显示是分开的。我们可以利用这一特性(win7和win8是没有的),来实现动态壁纸。因为我们只要将我们的程序插入到壁纸和图标之中,就可以想显示什么就显示什么了。

但是,这里要打一下茬,因为,Win10有一个多桌面的功能。但凡只要一按下这个按钮:

Windows的桌面底层就变成这个样子。

一看,SysListView32、SHELLDLL_DefView窗口Progman窗口分 家 了。而且还多了WorkerW窗口出来,而且不止一个。当初我也很奇怪,怎么就变成这个样子了。后来翻翻资料。其实,多一个WorkerW窗口是为了在切换桌面时能平滑过渡,而不是一闪一亮式的切换创建的。只要你把下面那一个没有子窗口的WorkerW关闭了,你就能体验到什么叫生硬的桌面切换。

其实这个样子,还是能够利用win10桌面的特性来达到我们的目的。但多少会造成影响(后面会说解决方法)。这里多说一句,我也不知道为什么,WorkerW其实是有很多的,如下:

这是我写的一个小程序找出来的WokerW窗口的数量和句柄,我也不知道这么多有什么用。

 

三、编写代码

Progman是显示壁纸的,我们只要把自己的窗口放在它之前就得了,就是把自己的窗口设立为Progman的子窗口。要注意隐藏没有子窗口的WorkerW窗口,它负责平滑过渡,也就是说它在Progman的前面绘制,我们必须隐藏它,才能正常显示我们的窗口。

上代码(正论)

#include <iostream>
#include <windows.h>
#include <string>//与桌面相关的窗口句柄
HWND SysListView32 = nullptr;
HWND SHELLDLL_DefView = nullptr;
HWND WorkerW = nullptr;
HWND Program = nullptr;//报告错误
void Error(const char* _error,const char* _from)
{std::cout<<"Error:"<<_error<<" From:"<<_from<<std::endl;
}//EnumWindows的回调函数
inline BOOL CALLBACK EnumWindowsProc(_In_ HWND TopHandle, _In_ LPARAM topparamhandle)
{char str[256];GetClassName(TopHandle,str,256);std::string s1 = str;//检查窗口是否叫WorkerWif(s1 == "WorkerW"){//检查是否有子窗口SHELLDLL_DefViewHWND def = FindWindowEx(TopHandle,nullptr,"SHELLDLL_DefView",nullptr);if(nullptr != def){WorkerW = TopHandle;SHELLDLL_DefView = def;}else{ShowWindow(TopHandle,SW_HIDE);}}return true;
}//设置桌面的环境
//获取所有相关的句柄
bool SetDeskEnvironment()
{const char *ErrorF = "SetDeskEnvironment";//获取Program句柄Program = FindWindow("Progman","Program Manager");if(nullptr == Program){Error("Can't Get Program Hwnd",ErrorF);return false;}//发送信息,让Windows生成WorkerSendMessageTimeout(Program, 0x052c, 0 ,0, SMTO_NORMAL, 0x3e8,nullptr);EnumWindows(EnumWindowsProc,(LPARAM)nullptr);//获取SysListView32句柄SysListView32 = FindWindowEx(SHELLDLL_DefView,nullptr,"SysListView32","FolderView");if(nullptr == SysListView32){Error("Can't Get SysListView32 Hwnd",ErrorF);return false;}return true;
}//设置窗口为桌面背景
bool SetWallWindow(LPCSTR ClassName,LPCSTR TitleName)
{const char *ErrorF = "SetWallWindow";//寻找要植入桌面的窗口的句柄HWND hWall = FindWindow(ClassName,TitleName);if(nullptr == hWall){Error("Can't Get hWall Hwnd",ErrorF);return false;}if(nullptr == Program){Error("Not get Program Hwnd",ErrorF);return false;}//把窗口设立为Progman的子窗口HWND hPro = SetParent(hWall,Program);if(nullptr == hPro){Error("Set Parent Failed",ErrorF);return false;}return true;
}int main()
{std::cout<<"Program Start!"<<std::endl;SetDeskEnvironment();SetWallWindow(nullptr,"ACGLooking");std::cout<<"Press any key..."<<std::endl;getchar();return 0;
}

在这段代码中,我用EnumWindows遍历一边,找到合适的Worker窗口,全部隐藏。而后就把自己的窗口设置为Progman的子窗口,就得到了我们想要的功能。而后我们只需要用WPF或Qt写一个漂亮的动态壁纸,就万事大吉了(如果能这么轻松的解决问题就好了 悲)。

还记得我说的Progman和自己的两个子窗口分家的问题吗。它们分家的时机就是收受到一个message,一个微软就没有公开的message,连宏定义都没有。只要向Progman窗口发送这个消息,Progman就自动分家。相关代码如下:

 SendMessageTimeout(Program, 0x052c, 0 ,0, SMTO_NORMAL, 0x3e8,nullptr);

 

下面展示一下效果图:

 

 

这种方案还有很多问题,比如只要一启动win10的多窗口,就会。。。

(突出了)

这个问题留到以后再解决把。

 

 

如果文章的内容有错误的,欢迎纠错。

同时,希望能有大神回答我的疑问。

欢迎大家一起来交流和学习。

 

 

 

 

 

 

 


http://www.ppmy.cn/news/297165.html

相关文章

Dota英雄装备配置(转)

<script languagejavascript srchttp://ad.paqiang.com.cn/Header.js></script>以下将简单介绍下东南亚战术,希望各位踊跃尝试新战术.随着cpl的结束,预测国内比赛将会普遍采用6.37版本,利用新的战术.击败传统强队不再是梦,抓住这个机会,国内dota界实力排行也不会再…

爬取wall.alphacoders.com下的英雄联盟壁纸,爬虫完整过程

爬取League of Legends壁纸 详细思路与过程 网址&#xff1a;https://wall.alphacoders.com/search.php?searchLeagueofLegends 把鼠标放置某一张图片上&#xff0c;就会出现该图片的link: 右键&#xff0c;查看网页源代码(没有这个选项的就换个浏览器&#xff09;&#xf…

ubuntu桌面配置 | dota类游戏

ubuntu打扮起来&#xff0c;那可是相当的炫&#xff0c; 快捷键&#xff1a; alt鼠标左键 拖动窗口 超级键鼠标中间滚动键 放大貌似真3D shift ctrl alt 方向键 平滑将窗口从一个桌面移到另一个桌面 超级键 tab ctrl 超级键 水纹显示 ctrl alt 下 平面显示…

打dotaⅡ

在DOTA2中&#xff0c;乞求者卡尔可以召唤三种元素&#xff0c;冰(Quas)&#xff0c;雷(Wex)&#xff0c;火(Exort)&#xff0c;当你按下Q时&#xff0c;他会召唤一个冰元素&#xff0c;按下W召唤雷元素&#xff0c;按下E召唤火元素。所有元素总数量最大为3&#xff0c;这意味着…

dota英雄全称

注意&#xff1a;英雄名称排序依次为 本名-英雄名-简称-中文名 Sentinel Taverns 近卫 A&#xff1a;Morning Tavern 清晨酒馆 ShendelzareSilkwood-TheVengefulSpirit-VS-复仇之魂 Zeus-LordofOlympia-Zeus&Mk-众神之王 Aiushtha-TheEnchantress-Ench&EH-魅惑魔女 Mor…

Dota全图那些事儿

Dota全图那些事儿 很早就着手研究全图了&#xff0c;也准备很多相关知识。由于自己编程基础比较差&#xff0c;恶补了不少知识&#xff0c;主要是硬生生的啃了大半本的《windows核心编程》。看这本书的过程中&#xff0c;有很多不懂得&#xff0c;但我适当跳过了&#xff08;其…

自己给dota开图

dota玩了很多很多年&#xff0c;其中知道有些玩家很假&#xff0c;但是心想开图毕竟是少数&#xff0c;直到自己开了一次图才发现&#xff0c;开图真不是少数&#xff0c;原因就是外挂程序太简单了&#xff0c;并不想深入&#xff0c;所以很多结构性代码我直接写死了&#xff0…