由自动切换桌面壁纸程序引发的感想

时间:2021-01-13 23:47:24
最近小弟想做一个自动切换桌面壁纸的程序,我之前记得SystemParametersinfo这个API好像可以实现,结果调试时才发现这个坑爹的API只能将BMP文件设为桌面壁纸,而且还不能设置居中、平铺和拉伸样式。

然后又在网上找了找,发现ACTIVEDESKTOP对象可以实现,但是我只找到C版本的,对于我这种C还停留在PRINTF水平上的人实在是无法翻译成VB版本的。

然后我又找啊找,终于找到了一个VB版本的,他说需要引用ADESKTOP.TLB,但是坑爹的是却没有给出这个文件。(http://hi.baidu.com/cnoldjohn/item/d186a02f2fa80e8c9c63d187)

于是我又在网上找ADESKTOP.TLB,好不容易找到了一个,却只是C源码,没有编译……(http://club.pchome.net/topic_5_53_20387__.html)

最后经过一些小修改,好不容易用MKTYPLIB把他编译出来了。

但是,我遇到问题从来都是想知其然,并且知其所以然!

我稍微看了一下这个TLB文件的C源码脚本,发现其中除了一些常数、类型(可能C中叫结构吧,WHATEVER。)、方法的声明以外,没有什么重要的自定义代码了。
其中最重要的就是几个CLSID的声明了,如:
[

 odl,

 uuid(F490EB00-1240-11D1-9888-006097DEACF9),

 helpstring(\"IActiveDesktop interface\")

 ]

[

 uuid(75048700-EF1F-11D0-9888-006097DEACF9),

 helpstring(\"ActiveDesktop class\")

 ]

[

 odl,

 uuid(56FDF342-FD6D-11d0-958A-006097C9A090),

 helpstring(\"ITaskbarList interface\")

 ]

[

 uuid(56FDF344-FD6D-11d0-958A-006097C9A090),

 helpstring(\"TaskBarList class\")

 ]

所以,我推断,程序中所有的方法、常数、类型等都是相应CLSID对象内原有的对外接口,有点像API函数,他们存在于各种DLL中,已经编译好了,程序使用时做一些固定声明即可。

那么,我的问题是:
1.作者是如何得知各个对象的CLSID的?(我在注册表中搜索了一下,IActiveDesktop interface找不到,ActiveDesktop class可以找到HKEY_CLASSES_ROOT\CLSID\)
2.这些对象固有的方法、常数、类型等如何获得?

再推广一步,这只是ActiveDesktop对象,如果是其他对象呢?又应该怎么写?

再进一步,这些资料或者是教程应该到哪里去学习?如果你简单的搜索C#教程可能涉及不到这些内容。

这个问题我同样在VB中时常遇到,当我还不知道有API这一神器存在的时候,如果我想编写一个VB程序,可以快速关机、重启,或者监视注册表变化之类的,就无从下手!
当然你可以搜索关机、重启怎样用VB实现,但这不是解决问题的根本方法,如果以后再遇到其他问题呢?例如我在这篇帖子最后的回复中提到的BUG,我到现在还毫无头绪:http://bbs.csdn.net/topics/390455028

如果简单搜索VB教程神马的,可能大多数都是用来应付国家计算机二级VB考试用的,当时我已经全部都会了。

同样的情况,也会在这个问题中出现,如果我简单搜索C#高级教程,可能内容比国家计算机二级C多一点,但是不一定会涉及到我上述提到的问题。

很多时候,并不是因为我伸手党,我也想学习,可不知道从何系统学起。。。

6 个解决方案

#1


在 XP 系统下
看注册表  HKEY_CURRENT_USER\Control Panel\Desktop\ 分支
ConvertedWallpaper 项是原始的图片,可以是 bmp、jpg、png……
Wallpaper 项是显示用的图片,从原始图片转换为 bmp 格式,连路径都是固定的 C:\Documents and Settings\<用户名>\Local Settings\Application Data\Microsoft\Wallpaper1.bmp
所以桌面图片必须是 bmp。
WallpaperStyle 项和  TileWallpaper 一起决定居中、平铺和拉伸样式。

换墙纸很简单:
直接替换 Wallpaper1.bmp 文件,然后设置相应的注册表,最后用下面的语句发个通知进行刷新就可以了。
SystemParametersInfo SPI_SETDESKWALLPAPER, 0, ByVal 0&, SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE

#2


好吧……
还是先感谢一下2楼的回复。
其实帖子中我已经由ADESKTOP.TLB库使用ACTIVEDESKTOP对象解决桌面壁纸的问题了。

我发这个帖子主要不是为了请教怎么解决切换桌面壁纸这个问题,而是解决这个问题的方法,或者说系统解决所有类似的问题。

给定一个对象的CLSID和接口IID,而VB库中默认没有包含这个对象时,在C中好像就能很方便的引用这个对象,使用他提供的接口方法等。但是在VB中,也许也能做到,只是我不知道,或者根本做不到,必须先由C将对象的接口方法编译成TLB库文件,再到工程里引用才行。

还有,我隐约感觉到VB中的CREATEOBJECT函数其实就是对CoCreateInstance的封装,如果能知道其中的细节,应该就可以解决任意对象动态引用的问题。

#3


就是后期绑定。
Dim cn as object
Set cn = CreateObject("ADODB.Connection")
cn.Open "..."

不适合一个对象实现多接口,并且多个接口之间有同名成员的情况。

#4


我表示用SystemParametersinfo可以设置壁纸而且可以设置居中拉升

#5


引用 3 楼 Tiger_Zhao 的回复:
就是后期绑定。
Dim cn as object
Set cn = CreateObject("ADODB.Connection")
cn.Open "..."

不适合一个对象实现多接口,并且多个接口之间有同名成员的情况。


好吧,就算是使用晚期绑定,对于这个例子,我想要使用ACTIVEDESKTOP OBJECT,调用CreateObject时应该怎么写类名呢?调用完成之后该对象的一些方法我如何得知呢?

类似的,所有由CreateObject产生绑定的对象,其类名和方法该如何得知呢?

#6


后期绑定只是一种调用方式,编程离不开帮助手册,无论哪种语言都一样。

#1


在 XP 系统下
看注册表  HKEY_CURRENT_USER\Control Panel\Desktop\ 分支
ConvertedWallpaper 项是原始的图片,可以是 bmp、jpg、png……
Wallpaper 项是显示用的图片,从原始图片转换为 bmp 格式,连路径都是固定的 C:\Documents and Settings\<用户名>\Local Settings\Application Data\Microsoft\Wallpaper1.bmp
所以桌面图片必须是 bmp。
WallpaperStyle 项和  TileWallpaper 一起决定居中、平铺和拉伸样式。

换墙纸很简单:
直接替换 Wallpaper1.bmp 文件,然后设置相应的注册表,最后用下面的语句发个通知进行刷新就可以了。
SystemParametersInfo SPI_SETDESKWALLPAPER, 0, ByVal 0&, SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE

#2


好吧……
还是先感谢一下2楼的回复。
其实帖子中我已经由ADESKTOP.TLB库使用ACTIVEDESKTOP对象解决桌面壁纸的问题了。

我发这个帖子主要不是为了请教怎么解决切换桌面壁纸这个问题,而是解决这个问题的方法,或者说系统解决所有类似的问题。

给定一个对象的CLSID和接口IID,而VB库中默认没有包含这个对象时,在C中好像就能很方便的引用这个对象,使用他提供的接口方法等。但是在VB中,也许也能做到,只是我不知道,或者根本做不到,必须先由C将对象的接口方法编译成TLB库文件,再到工程里引用才行。

还有,我隐约感觉到VB中的CREATEOBJECT函数其实就是对CoCreateInstance的封装,如果能知道其中的细节,应该就可以解决任意对象动态引用的问题。

#3


就是后期绑定。
Dim cn as object
Set cn = CreateObject("ADODB.Connection")
cn.Open "..."

不适合一个对象实现多接口,并且多个接口之间有同名成员的情况。

#4


我表示用SystemParametersinfo可以设置壁纸而且可以设置居中拉升

#5


引用 3 楼 Tiger_Zhao 的回复:
就是后期绑定。
Dim cn as object
Set cn = CreateObject("ADODB.Connection")
cn.Open "..."

不适合一个对象实现多接口,并且多个接口之间有同名成员的情况。


好吧,就算是使用晚期绑定,对于这个例子,我想要使用ACTIVEDESKTOP OBJECT,调用CreateObject时应该怎么写类名呢?调用完成之后该对象的一些方法我如何得知呢?

类似的,所有由CreateObject产生绑定的对象,其类名和方法该如何得知呢?

#6


后期绑定只是一种调用方式,编程离不开帮助手册,无论哪种语言都一样。