zoukankan      html  css  js  c++  java
  • 如何在程序中动态设置墙纸(使用IActiveDesktop接口)

    大家都知道设置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_USERControl PanelDesktop的值来做到这一点)
      由于在显示属性系统对话框内很容易手动设置这些选项,我们有理由相信,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;
      }

    http://www.cnblogs.com/lzjsky/archive/2011/01/17/1937514.htm

  • 相关阅读:
    背水一战 Windows 10 (26)
    背水一战 Windows 10 (25)
    背水一战 Windows 10 (24)
    背水一战 Windows 10 (23)
    背水一战 Windows 10 (22)
    背水一战 Windows 10 (21)
    背水一战 Windows 10 (20)
    背水一战 Windows 10 (19)
    背水一战 Windows 10 (18)
    背水一战 Windows 10 (17)
  • 原文地址:https://www.cnblogs.com/findumars/p/5625045.html
Copyright © 2011-2022 走看看