自制壁纸小工具

之前用win10自带的壁纸工具总感觉有些不方便,有些不喜欢的壁纸不能够删除,喜欢的也不能收藏,于是自己用mfc做了一个。

实现的功能如下:

1.开机自启动

2.自动缩小到系统托盘

3.快捷键实现壁纸切换,收藏和删除

其中还是有些知识点需要注意的

1)是开机自启动功能,这个地方有些问题的是我在OnInitDialog里做了读取文件的操作,但是当设置为自启动的时候程序的启动路径不是原来的了,导致文件读取失败,有类似读取配置文件的操作的时候需要特别注意

bool CBeautyDlg::autoRun(bool run)//自启动设置
{
	HKEY hKey;
	LPCTSTR lpRun = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
	long lRet = RegOpenKeyEx(HKEY_CURRENT_USER, lpRun, 0, KEY_ALL_ACCESS, &hKey);
	if (lRet == ERROR_SUCCESS)
	{
		if (run)
		{
			char pFileName[MAX_PATH] = { 0 };
			//得到程序自身的全路径 
			DWORD dwRet = GetModuleFileName(NULL, pFileName, MAX_PATH);
			//添加一个子Key,并设置值 
			lRet = RegSetValueEx(hKey, "Beauty", 0, REG_SZ, (BYTE*)pFileName, dwRet);
			if (lRet != ERROR_SUCCESS)
				AfxMessageBox("系统参数错误,不能随系统启动");
		}
		else
			RegDeleteValue(hKey, "Beauty");
		RegCloseKey(hKey);
	}
	else
	{
		RegCloseKey(hKey);
		return false;
	}
	return true;
}

2)程序启动时需要自动隐藏显示并缩小到系统托盘,这个地方有个问题是一开始在OnInitDialog调用ShowWindow(SW_HIDE);是没有效果的,网上也有比较多的方法,我找到一种比较好的方法是在OnInitDialog增加以下代码

MoveWindow(0, 0, 0, 0);//将窗口移动看不见的地方
ShowWindow(SW_HIDE);//然后调用隐藏

ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);

这样处理后,需要在点击托盘后重新恢复显示

MoveWindow(rect.top, rect.left, rect.Width(), rect.Height() * 1.1);
 CenterWindow();
 ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW);
 this->ShowWindow(SW_SHOW);

这样程序开始的时候就不会出现界面了,而且也不会出现闪烁的情况

3)设置托盘的时候也要注意一点,在程序关闭的时候需要调用Shell_NotifyIcon(NIM_DELETE,&nid);//在托盘区删除图标,这句可以加在重载的destroywindow的函数里,不加的话会出现系统图标残留的情况

nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
	nid.hWnd = this->m_hWnd;
	nid.uID = IDR_MAINFRAME;
	nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP ; 
	nid.uCallbackMessage = WM_SHOWMAIN;//自定义的消息名称 
	nid.hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME)); 
	strcpy(nid.szTip,"我的壁纸");//信息提示条为“我的壁纸” 
	Shell_NotifyIcon(NIM_ADD,&nid);//在托盘区添加图标
	ShowWindow(SW_HIDE);//隐藏主窗口
	m_bShow = false;

4)设置壁纸的操作,根据规定操作执行就行了

BOOL CBeautyDlg::SetWallPaper(CString strPath)
{
	HRESULT hr;
	IActiveDesktop* pIAD;
	//Applications must initialize the COM library before they can call COM library functions 
	CoInitialize(NULL);
	//创建接口的实例
	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 = strPath.GetBuffer(strPath.GetLength());
	MultiByteToWideChar(CP_ACP, 0, lpStr, -1, wszWallpaper, MAX_PATH);
	strPath.ReleaseBuffer();
	//设置墙纸
	hr = pIAD->SetWallpaper(wszWallpaper, 0);
	if (!SUCCEEDED(hr)) return FALSE;
	//设置墙纸的样式
	WALLPAPEROPT wpo;
	wpo.dwSize = sizeof(wpo);
	wpo.dwStyle = WPSTYLE_CENTER;
	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();
	CoUninitialize();
	return TRUE;

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章