• 如何在程序中动态设置墙纸(使用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

  • 相关阅读:
    在浏览器中输入url后执行的全过程
    自己搭建一个类似vue,实现响应式的原理
    关于vue是怎么放到服务器上运行的基于vue-cli3
    vue v-modal语法糖
    js中的Map和Set
    js的reduce方法
    vue双向绑定原理
    js对象原型-class类
    (二)仅仅通过Application监听用户行为及App的在线状态和在线时长
    (一)仅仅用ApplicationContext加载界面
  • 原文地址:https://www.cnblogs.com/findumars/p/5625045.html
Copyright © 2020-2023  润新知