之前用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;
}