如何在程式中動態設定牆紙

來源:互聯網
上載者:User

大家都知道設定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;
}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.