c++编程 设置桌面壁纸以及设置壁纸失效的解决办法
最近项目中需要一个小工具来设置桌面壁纸,于是想自己尝试用c++写一个。
刚开始,发现COM组件IActiveDesktop 可以设置壁纸。代码如下:
class CCoInitialize {
public:
CCoInitialize() : m_hr(CoInitialize(NULL)) { }
~CCoInitialize() { if (SUCCEEDED(m_hr)) CoUninitialize(); }
operator HRESULT() const { return m_hr; }
HRESULT m_hr;
};
// 设置桌面壁纸(active)
int ApplyWallpaper(char* szFileDirParam, int displayStyle)
{
wchar_t* szFileDir = U8ToUnicode(szFileDirParam);
CCoInitialize initCom;
HRESULT hr;
int errNum = 0;
std::wstring x = szFileDir;
DWORD dwStyle = displayStyle;
IActiveDesktop* pIAD;
hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
IID_IActiveDesktop, (void**)& pIAD);
if (!SUCCEEDED(hr))
{
errNum = GetLastError();
return errNum ;
}
hr = pIAD->SetWallpaper(x.c_str(), 0);
if (!SUCCEEDED(hr))
{
errNum = GetLastError();
return errNum;
}
WALLPAPEROPT wpo;
wpo.dwSize = sizeof(wpo);
wpo.dwStyle = dwStyle;
hr = pIAD->SetWallpaperOptions(&wpo, 0);
if (!SUCCEEDED(hr))
{
errNum = GetLastError();
return errNum;
}
hr = pIAD->ApplyChanges(AD_APPLY_ALL);
if (!SUCCEEDED(hr))
{
errNum = GetLastError();
return errNum;
}
pIAD->Release();
return TRUE;
}
上面这段代码在大多数据情况下,能成功设置壁纸.在实际环境中,发现某些windows10镜像,有窗口覆盖桌面的情况下,不能正确设置壁纸(新壁纸闪现,然后又回到原始桌面壁纸)。看了MSDN,了解到,IActiveDesktop仅用于激活的桌面(原话:“Sets the wallpaper for the Active Desktop.”)。个人猜测是因为有其他窗口覆盖桌面后,桌面状态不是active了,所有设置失效。
后面发现另外一个COM组件 ------ IDesktopWallpaper,该组件同样提供设置桌面壁纸功能。并且没强调需要桌面是激活状态(原话:“Sets the desktop wallpaper.”)。代码如下:
class CCoInitialize {
public:
CCoInitialize() : m_hr(CoInitialize(NULL)) { }
~CCoInitialize() { if (SUCCEEDED(m_hr)) CoUninitialize(); }
operator HRESULT() const { return m_hr; }
HRESULT m_hr;
};
// 设置桌面壁纸
int ApplyWallpaperEx(char* szFileDirParam, int displayStyle)
{
wchar_t* szFileDir = U8ToUnicode(szFileDirParam);
CCoInitialize initCom;
HRESULT hr;
int errNum = 0;
std::wstring x = szFileDir;
DWORD dwStyle = displayStyle;
IDesktopWallpaper* pIAD;
hr = CoCreateInstance(__uuidof(DesktopWallpaper), 0, CLSCTX_LOCAL_SERVER, __uuidof(IDesktopWallpaper), (void**)&pIAD);
if (!SUCCEEDED(hr))
{
errNum = GetLastError();
return errNum ;
}
// Set first param to NULL to set the wallpaper image on all monitors.
hr = pIAD->SetWallpaper(NULL, x.c_str());
if (!SUCCEEDED(hr))
{
errNum = GetLastError();
return errNum ;
}
WALLPAPEROPT wpo;
wpo.dwSize = sizeof(wpo);
wpo.dwStyle = dwStyle;
hr = pIAD->SetPosition(DESKTOP_WALLPAPER_POSITION(dwStyle));
if (!SUCCEEDED(hr))
{
errNum = GetLastError();
return errNum ;
}
if (!SUCCEEDED(hr))
{
errNum = GetLastError();
return errNum ;
}
pIAD->Release();
return TRUE;
}
以代码可以不用理会桌面是否处于激活状态,都能成功设置桌面壁纸。
工作遇到问题,Mark一下。如果你正好需要,欢迎转载or复制。