分享
 
 
 

在C++ Builder中实现桌布自动更新

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在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_USER\Control Panel\Desktop键)

键名

含义

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 Panel\\Desktop”,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函数设置桌布即可搞定.

JPEG格式转换为位图:

#include <jpeg.hpp>

bool __fastcall TForm1::JPEGToBMP(AnsiString jpegFile,AnsiString bmpFile)

{

//TODO: Add your source code here

TJPEGImage *jpeg = new TJPEGImage();

jpeg->LoadFromFile(jpegFile);

Graphics::TBitmap *bitmap = new Graphics::TBitmap();

try {

bitmap->Assign(jpeg);

bitmap->SaveToFile(bmpFile);

}

__finally {

delete jpeg;

delete bitmap;

}

return true;

}

遗憾的是BCB不直接支持如PNG,GIF等格式与位图的转换,希望在BCB6.0以后的版本中会得到支持.如果要进行PNG,GIF格式的转换,我们可以去寻求控件,这是最简单的办法,还有一种就是自己编写图形格式转换的程序,这个比较困难.首先要知道各种图形格式的标准,然后编写格式转换的算法,这是最重要的,最后进行编码.还有一点我也想说一下,如果你足够细心的话,可能已经发现了我在实现Timer1Timer(TObject *Sender)这个函数的时候用到了一个RebuildIconCache()函数,注释说是重建系统缓存,其实是这样的当你改变了桌布的时候,可能系统来不及重新绘制桌布,这时你需要手动地按下F5来进行刷新,但我们的程序总不能去叫用户刷新吧,所以我增加了一个RebuildIconCache()函数来完成此功能,它是这样实现的。

void __fastcall TForm1::RebuildIconCache()

{

//TODO: Add your source code here

int IconW;

IconW= GetSystemMetrics(SM_CXICON);

TRegIniFile *Reg = new TRegIniFile("Control Panel\\Desktop");

try

{

Reg->WriteString("WindowMetrics", "Shell Icon Size", IntToStr(IconW));

SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0);

}

__finally

{

delete Reg;

}

}

这样只要你改变了桌布设置,再广播WM_SETTINGCHANGE窗口消息,系统就会进行桌布的重新绘制。

提示:如果你想自己体会一下这个程序的功能,你不必通过键盘的输入来达到目的,http://www.zccfamily.com/zqget/ 提供了这个程序的所有源代码,你可以去下载来看一下实际的效果。

在阅读本文的过程中,无论是心存感激(我帮你解决了问题)还是心有疑惑(这是不是你的原创,还是在其它地方去抄的),或者对本文有什么评价的话,我的联系方式:

mailto:zqget@msn.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有