如何在程序中动态设置墙纸

原创 2002年12月30日 09:24:00

大家都知道设置WINDOWS桌面墙纸的WIN32 API是SystemParametersInfo, 使用SPI_SETDESKWALLPAPER参数便能设置墙纸:


::SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "C://ABitmap.bmp", SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);

但问题并没有解决,因为这个WIN32 API有很大的局限性
1. 无法把jpeg, gif等其他非位图格式的图片设为墙纸。
2. 无法调整墙纸的式样,即无法设置墙纸为居中,平铺或拉伸。(当然我们可以通过编程改变注册表HKEY_CURRENT_USER/Control Panel/Desktop的值来做到这一点)

由于在显示属性系统对话框内很容易手动设置这些选项,我们有理由相信,Windows Shell API一定提供了相应的比较高层的函数,接口或类来完成墙纸的设置。事实上,Windows Shell API中确实存在完成这个任务的接口:IActiveDesktop。

以下是我所完成的设置墙纸的函数
//strPicFile是图像文件名,支持BMP JPEG GIF等格式
//dwStyle是墙纸的样式
//WPSTYLE_CENTER 居中 0
//WPSTYLE_TILE 平铺 1
//WPSTYLE_STRETCH 拉伸 2
//WPSTYLE_MAX 3
//返回值是TRUE时墙纸设置成功,返回FALSE时失败
BOOL SetWallpaper(CString &strPicFile, DWORD dwStyle)
{
  HRESULT hr;
  IActiveDesktop* pIAD;
  //创建接口的实例
  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();
  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;
  //创建接口的实例
  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;
  return TRUE;
}

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

如何在程序中动态设置墙纸

大家都知道设置WINDOWS桌面墙纸的WIN32 API是SystemParametersInfo, 使用SPI_SETDESKWALLPAPER参数便能设置墙纸:::SystemParameters...
  • goingup
  • goingup
  • 2006年04月03日 19:02
  • 887

iOS 设置头像圆角效果

前言在项目中,经常需要用到设置头像的圆角效果。设置圆角效果其实很简单,有两种方法,一种方法是通过设置view的圆角来实现,另一种是给view添加遮罩层。方法一:设置圆角 UIImageView *im...
  • u010545480
  • u010545480
  • 2016年02月16日 17:40
  • 608

如何在Delphi中更改墙纸

你学会了VB,你知道了在VB中如何通过程序来更换Windows的墙纸,但是,在Delphi中如何同VB一样方便地更换墙纸呢?其实,也是很方便的,不信?请参考以下的程序。   procedureChan...
  • dingligang
  • dingligang
  • 2005年01月14日 18:29
  • 531

让您的Ubuntu桌面壁纸动态变化

    最近一直还Ubuntu的桌面背景动态变化的只有那么2个目录而烦恼,网上找了下资源,发现一xml脚本生成工具。这是因为要动态改变需要一个xml脚本语言,本perl脚本用于生成xml脚本文件。具体...
  • computer055maxi
  • computer055maxi
  • 2010年12月03日 20:31
  • 2789

如何在代码中动态设置java_library_path?

在使用Java JNI的时候,往往需要在程序启动前设定"java.library.path"  1. 在终端情况下,java -Djava.library.path=/path/to/libs 2. ...
  • u011876597
  • u011876597
  • 2013年08月29日 18:14
  • 110

Android apk代码中动态设置背景图片

Android apk中有时候需要识别场景动态设置背景图片,而不是写死在布局文件中。 这里介绍2中方式动态设置背景图片。 布局文件activity_hello.xml为:    ...
  • Q1009355422
  • Q1009355422
  • 2016年08月04日 14:18
  • 4447

动态墙纸

动态墙纸的是一个比较特殊的APK。 Android动态墙纸的本质是一个“Service”,这个Service通过AndroidManifest.xml文件中Service的intent-filt...
  • lili1985516
  • lili1985516
  • 2014年05月30日 16:08
  • 523

PPT2016内嵌Excel的动态图表

背景 在excel中可以通过窗体或ActiveX控件达到动态控制图表显示的目的,但当Excel图表作为对象内嵌到PPT后,在PPT播放模式下,所有在Excel对象中的控件都是不可选的,只能在PPT的编...
  • u012493828
  • u012493828
  • 2017年12月05日 15:56
  • 178

如何在Android程序中设置代理

有时候需要在程序中使用代理服务器,可以在建立网络链接的代码之前添加以下代码: Properties prop = System.getProperties(); // pro...
  • sxwyf248
  • sxwyf248
  • 2011年11月25日 16:47
  • 4206

mtk平台 默认壁纸和壁纸修改

在framework/base/core/res/res/drawable-nodip/default_wallpaper.png下 ,default_wallpaper.png即为默认壁纸的名字 ,...
  • IWantADonkey
  • IWantADonkey
  • 2015年06月24日 16:53
  • 487
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何在程序中动态设置墙纸
举报原因:
原因补充:

(最多只允许输入30个字)