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;
//创建接口的实例
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;
}
使用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;
}
相关文章推荐
- (五下)安装ffi模块,使用electron调用win32 api, win32项目设置父子窗口关系
- python调用win32下的API__&&__Win32Com__[转]使用 python 写 COM
- Python使用win32 COM实现Excel的写入与保存功能示例
- Win32 网络API使用详细说明
- 使用Win32 API创建串口通讯程序
- salesforce 零基础学习(五十一)使用 Salesforce.com SOAP API 实现用户登录以及简单的增删改查(JAVA访问salesforce)
- Delphi Win32 API 使用的特殊情况
- 使用内部(com.android.internal)和隐藏(@hide)API[第2部分,定制android.jar]
- ArcGIS API for Javascript 使用缓冲区结果做query查询出现“esri.config.defaults.io.proxyUrl 尚未进行设置”错误
- C#中通过DllImport使用 Win32 API
- PYTHON 调用EXCEL VBA 函数:使用win32com模块
- 图解使用Win8Api进行Metro风格的程序开发五----在系统的设置窗口添加按钮
- 你还在为使用P/Invoke时,写不出win32 api对应的C#声明而犯愁吗?
- ArcGIS API for Javascript 使用query查询以某个点为半径的圆内的要素出现“esri.config.defaults.io.proxyUrl 尚未进行设置”错误
- C++ 使用API设置文件属性 隐藏
- vb6如何设置和获取 cookie,使用 WinInet api url
- 学习win32 API开发7-在窗口中使用控件
- 在.NET平台使用Google Earth COM API示例(03)
- vs 2008 win32程序使用大内存 (>2GB)设置
- C#中通过DllImport使用 Win32 API