首页 | 互联网 | IT动态 | 网络设备 | 服务器 | IDC | 安全 | Cisco | Windows | Linux | Java | .Net | Oracle | CIW | 华为 | 专题
IT技术 | 网页设计 | 平面设计 | 电子书下载 | 教学视频 | 方案 | 数字网校 | 直播室 | 虚拟考场 | 面授培训 | 搜索 | 博客 | 沙龙 | 论坛
首页 | JAVA | C# | VB | VB.NET | C/C++ | delphi | 工程管理 | 其他语言 | 论坛
免费注册一站通帐号,参与直播、论坛、下载、博客、网摘、评论,展现我的风采!
您现在的位置: 中国IT实验室 >> 桌面开发 >> VC >> 文章正文
用C++ Builder实现桌布自动更新
来源:中国IT实验室整理  时间:2007-4-4

 在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键)
  

  注意:
  其实,上表还漏了TileWallpaper键,这个设定值的优先级最高,即当TileWallpaper这个值为1时,不管其它参数为何值,都会将桌布填满桌面,为了简化程序,一般将其设置为0,然后在根据WallPaperStyle来设置桌布样式,这是比较明智的做法。
  
  在了解了与桌布相关的注册表的设置情况后,那我们就进入具体的桌布设置吧!
  
  #include
  
  //先在注册表里添好桌布样式,在设置桌布
  
  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
  
  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/ 提供了这个程序的所有源代码,你可以去下载来看一下实际的效果。
【责编:Lili】

中国IT教育热线咨询

相关文章
编程软件系列之C++编程技巧
C++中确定基类有虚析构函数
如何在C++中动态分配二维数组
使用C++异常来取代exit()函数
Linux下C++异常处理技巧-实例讲解
详细解析C++编写的ATM自动取款机模拟程…
Delphi与C++之间通过实现函数与对象共享
在Visual Basic 中使用C++ 类
推荐文章
· 用C#创建COM对象
· IT管理十大失误及其对策
· VC中利用MFC设计绘图程序初步
· JAVA中对象创建和初始化过程
· C语言中的位域的使用
· 浅谈Java桌面应用程序开发
· C#的前途如何?
· 几种VC++数据库开发技术的相对比较
 精彩友情推荐
·锐捷交换机报价
·锐捷交换机
·锐捷网络网络交换机
·smc交换机
·smc交换机报价
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
最新更新 推荐文章
·Visual Basic 9.0隐式类型的局部…09-30
·JMX+J2SE5.0实现Web应用的安全管…09-30
·多线程、Socket技术及委托技术的…09-21
·Visual C#多线程参数传递浅析09-21
·浅谈Java中利用JCOM实现仿Excel编…09-21
·基于Java的界面布局DSL的设计与实…09-21
·Java开发中的事件驱动模型实例详…09-21
·并发工程原则应用到软件项目中09-06
·Delphi初学者应小心的六大陷阱09-06
·VC开发多语言界面支持的简单方法09-06
·用C#创建COM对象09-06
·用C#创建COM对象09-06
·IT管理十大失误及其对策08-30
·VC中利用MFC设计绘图程序初步08-23
·JAVA中对象创建和初始化过程08-23
·C语言中的位域的使用08-09
·浅谈Java桌面应用程序开发08-09
·C#的前途如何?08-02
·几种VC++数据库开发技术的相对比较07-12
·用Visual C#实现网络封包监视07-12
·VB.NET中的TextBox控件详解07-12
·VB.NET实现PC与掌上电脑PPC的双向通信07-05
  培训中心