您的位置:首页 > 其它

win32 使用COM和API设置动态壁纸

2013-04-17 16:39 239 查看
 大家都知道设置WINDOWS桌面墙纸的WIN32API是SystemParametersInfo,
使用SPI_SETDESKWALLPAPER参数便能设置墙纸:
         ::SystemParametersInfo(SPI_SETDESKWALLPAPER,0,
"C:\\ABitmap.bmp",SPIF_SENDWININICHANGE
|SPIF_UPDATEINIFILE);
  但问题并没有解决,因为这个WIN32API有很大的局限性
  1.无法把jpeg,
gif等其他非位图格式的图片设为墙纸。
  2.无法调整墙纸的式样,即无法设置墙纸为居中,平铺或拉伸。(当然我们可以通过编程改变注册表HKEY_CURRENT_USER\ControlPanel\Desktop的值来做到这一点)
  由于在显示属性系统对话框内很容易手动设置这些选项,我们有理由相信,WindowsShell
API一定提供了相应的比较高层的函数,接口或类来完成墙纸的设置。事实上,WindowsShell
API中确实存在完成这个任务的接口:IActiveDesktop。
  以下是我所完成的设置墙纸的函数
  //strPicFile是图像文件名,支持BMPJPEG
GIF等格式
  //dwStyle是墙纸的样式
  //WPSTYLE_CENTER居中
0
  //WPSTYLE_TILE平铺
1
  //WPSTYLE_STRETCH拉伸
2
  //WPSTYLE_MAX3
  //返回值是TRUE时墙纸设置成功,返回FALSE时失败
  BOOLSetWallpaper(CString
&strPicFile,DWORD
dwStyle)
  {
  HRESULT
hr;
  IActiveDesktop*
pIAD;

CoInitialize ( NULL ); 

   //创建接口的实例
   hr = CoCreateInstance ( CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
   IID_IActiveDesktop, (void**) &pIAD );
   if(!SUCCEEDED(hr)) return FALSE;
   //将文件名改为宽字符串,这是IActiveDesktop::SetWallpaper的要求
   WCHAR wszWallpaper [MAX_PATH];
   LPTSTR lpStr = strPicFile.GetBuffer(strPicFile.GetLength() );
   MultiByteToWideChar(CP_ACP, 0, lpStr, -1, wszWallpaper, MAX_PATH);
   strPicFile.ReleaseBuffer();
   //设置墙纸
   hr = pIAD->SetWallpaper(wszWallpaper, 0);
   if(!SUCCEEDED(hr)) return FALSE;
   //设置墙纸的样式
   WALLPAPEROPT wpo;
   wpo.dwSize = sizeof(wpo);
   wpo.dwStyle = dwStyle;
   hr = pIAD->SetWallpaperOptions(&wpo, 0);
   if(!SUCCEEDED(hr)) return FALSE;
   //应用墙纸的设置
   hr = pIAD->ApplyChanges(AD_APPLY_ALL);
   if(!SUCCEEDED(hr)) return FALSE;
   //读取墙纸的文件名并打印在debug窗口内
   hr = pIAD->GetWallpaper(wszWallpaper, MAX_PATH, 0);
   CString strFile = wszWallpaper;
   TRACE(strFile); //如果不用位图的话,这里有你意想不到的发现
   //释放接口的实例
   pIAD->Release();

CoUninitialize();
   return TRUE;
  }
  在MFC程序中应用此函数时,须注意以下三点。
  1.在函数所在文件中加上声明IActiveDesktop的头文件
  #include<shlobj.h>
  2.在StdAfx.h中插入#include <wininet.h>
  位置不能搞错,否则IActiveDesktop将找不到定义
  #include <afxwin.h> // MFC core and standard components
  #include <wininet.h> // NOTE: corrects compilation errors w/IActiveDesktop!!
  #include <afxext.h> // MFC extensions
  3.由于此函数引用了COM组件,所以必须在C**App::OnInitInstance()中插入以下语句,初始化COM组件。
  AfxOleInit();
  补充:
  只有在安装了IE4.0及以上版本时才能应用IActiveDesktop接口,只有在打开active desktop(活动桌面)的情况下才能应用SetWallpaper函数,下面是启用或关闭active desktop的函数:
  //bEnable是TRUE时启用active desktop, 是FALSE时关闭
  //返回值是TRUE时启用或关闭active desktop成功,返回FALSE时失败
  BOOL EnableActiveDesktop(BOOL bEnable)
  {
   HRESULT hr;
   IActiveDesktop* pIAD;

 CoInitialize ( NULL ); 

   //创建接口的实例
   hr = CoCreateInstance ( CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
   IID_IActiveDesktop, (void**) &pIAD );
   if(!SUCCEEDED(hr)) return FALSE;
   COMPONENTSOPT comp;
   comp.dwSize = sizeof(comp);
   comp.fEnableComponents = bEnable;
   //启用或关闭active desktop
   comp.fActiveDesktop = bEnable;
   hr = pIAD->SetDesktopItemOptions(&comp, 0);
   if(!SUCCEEDED(hr)) return FALSE;
   //释放接口的实例
   pIAD->Release;
CoUninitialize();

   return TRUE;
  }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: