在C++ Builder中要实现桌布的自动更换功能,我认为主要两个关键点,其一既然要“自动”那就免不了要用到定时器,我们可以用Timer这个组件来完成,这个还好解决,第二个问题可能比较麻烦了,我们如何来设置桌布,好像BCB中并没有提供什么组件,那我们也就只好自力更生了,虽说本人只是一只菜鸟,但这个问题还是难不了我,它主要是用到了SystemParametersInfo 这个Windows API函数,它的声明如下:
BOOL SystemParametersInfo(
UINT uiAction, // system parameter to query or set
UINT uiParam, // depends on action to be taken PVOID pvParam, // depends on action to be taken UINT fWinIni // user profile update flag );
|
它是一个非常重量级的函数,主要用来设置或获得系统范围上的相关参数(如:我正在介绍的“如何设置桌布”,还有如:系统字体,屏幕分辨率等),其实光从字面上也能大概知道它的作用。如果只是简单的调用SystemParametersInfo函数的话,问题就变得简单多了,但你要总不能只使用默认的桌布样式,所以在设置桌布之前还应先设置好桌布的样式,比如:桌布的显示位置,是否填满桌面等,然后再调用SystemParametersInfo函数,这个函数会根据注册表里的桌布样式设置情况来设置实际的桌布样式。
与桌布样式有关的注册表设定:(位于HKEY_CURRENT_USERControl PanelDesktop键)
键名 | 含义 | WallPaper | 桌布的文件名,但只限于BMP格式的位图 | WallPaperStyle | 设置桌布样式 若为0,桌布将以原始尺寸显示在桌面中央 若为1,桌布将填满桌面 若为2,将桌布放大的画面大小,图像有可能失真 | WallPaperOriginX | 如果WallPaperStyle为0,则这表示图像左上角X轴坐标 | WallPaperOriginY | 如果WallPaperStyle为0,则这表示图像左上角Y轴坐标 |
注意:
其实,上表还漏了TileWallpaper键,这个设定值的优先级最高,即当TileWallpaper这个值为1时,不管其它参数为何值,都会将桌布填满桌面,为了简化程序,一般将其设置为0,然后在根据WallPaperStyle来设置桌布样式,这是比较明智的做法。
在了解了与桌布相关的注册表的设置情况后,那我们就进入具体的桌布设置吧!
#include 〈Registry.hpp〉
//先在注册表里添好桌布样式,在设置桌布
TRegistry *Registry = new TRegistry; try { Registry-〉OpenKey(“Control PanelDesktop”,false); Registry-〉WriteString("TileWallpaper","0"); //设置桌布样式
Registry-〉WriteString("WallpaperStyle",wallStyle); } __finally { delete Registry; }
}
//设置桌布
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,FileName.c_str(),SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
|
在此,我们已经解决了最为关键的问题,剩下的关于设置定时器那就简单了,只需用一个定时器组件即可完成.
代码如下:
void __fastcall TForm1::Timer1Timer(TObject *Sender) { if (ListBox1-〉Items-〉Count〈=0) { return ; }
if (index〉=ListBox1-〉Items-〉Count) { index=0; }
//如果是JPG格式就将其转换为BMP格式,将其存到临时文件夹中
if(UpperCase(ListBox1-〉Items-〉Strings[index]).Pos(".JPG")|| UpperCase(ListBox1-〉Items-〉Strings[index]).Pos(".JPEG")) { AnsiString fileName=ExtractFileName(ListBox1-〉Items-〉Strings[index]); int len=fileName.LastDelimiter(".");
fileName=fileName.SubString(0,len-1)+".bmp";
unsigned int *size=new unsigned int(256);
char * buffer=new char[256];
GetTempPath(*size,buffer);
fileName=AnsiString(buffer)+fileName;
JPEGToBMP(ListBox1-〉Items-〉Strings[index],fileName);
//设置桌布
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,ListBox1-〉Items-〉Strings[index].c_str(), SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}
else
{
//设置桌布
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,ListBox1-〉Items-〉Strings[index].c_str(), SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}
//重建系统缓存
RebuildIconCache();
index++;
}
|
就这样,我们就完成了桌布自动更换的功能,是不是很简单,不过由于它受限于BMP位图格式,这一点总是使得桌布的爱好者十分苦恼.我们能不能让它支持其它格式的图形文件呢?当然可以,原理是这样的,在设置桌布之前,现将其它格式的文件转换为位图,在用SystemParametersInfo函数设置桌布即可搞定.
|