c++编程 设置桌面壁纸以及设置壁纸失效的解决办法

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复制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值