Windows 7系统中有个墙纸自动定时切换的功能,但Windows XP、Windows 2003中没有这个功能,网上搜索了一下,发现不少小工具,下载后才发现,竟然有病毒,于是自己做了个切换的小程序,用Windows自带的“任务计划”实现定时切换。源码不足200行,大多还是网上搜索来的,所以开源给大家用吧。
1 // SetWallpaper.cpp : 定义控制台应用程序的入口点。
2 //
3 #pragma comment(linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" )
4 #include <stdio.h>
5 #include <tchar.h>
6 #include <windows.h>
7 #include <wininet.h>
8 #include <shlobj.h>
9 #include <iostream>
10 #include <vector>
11 #include <string>
12 #include <algorithm>
13 using namespace std;
14 //设置墙纸函数
15 //strFileName是图像文件名,支持BMP JPEG GIF等格式
16 //dwStyle是墙纸的样式
17 //WPSTYLE_CENTER 居中 0
18 //WPSTYLE_TILE 平铺 1
19 //WPSTYLE_STRETCH 拉伸 2
20 //WPSTYLE_MAX 3
21 //返回值是TRUE时墙纸设置成功,返回FALSE时失败
22 BOOL SetWallpaper(wstring strFileName, DWORD dwStyle)
23 {
24 BOOL bReslt = FALSE;
25 HRESULT hr;
26 IActiveDesktop *pActiveDesktop;
27 //创建COM接口的实例
28 hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
29 IID_IActiveDesktop, (void**)&pActiveDesktop);
30 if(SUCCEEDED(hr))
31 {
32 //设置墙纸
33 hr = pActiveDesktop->SetWallpaper(strFileName.c_str(), 0);
34 if(SUCCEEDED(hr))
35 {
36 //设置墙纸的样式
37 WALLPAPEROPT wpo;
38 wpo.dwSize = sizeof(wpo);
39 wpo.dwStyle = dwStyle;
40 hr = pActiveDesktop->SetWallpaperOptions(&wpo, 0);
41 if(SUCCEEDED(hr))
42 {
43 //应用墙纸的设置,刷新桌面
44 hr = pActiveDesktop->ApplyChanges(AD_APPLY_ALL);
45 if(SUCCEEDED(hr))
46 bReslt = TRUE;
47 }
48 }
49 //释放COM接口实例
50 pActiveDesktop->Release();
51 }
52 return bReslt;
53 }
54 //从记录文件取得上个墙纸名称
55 wstring GetLastWallpaperName()
56 {
57 wstring strReslt;
58 FILE *stream;
59 errno_t err;
60 WCHAR szWP[MAX_PATH];
61 int numread = 0;
62 if( (err = fopen_s( &stream, "wallpaper.txt", "rt" )) ==0 )
63 {
64 numread = fread( szWP, sizeof( WCHAR ), MAX_PATH, stream );
65 }
66 if(stream)
67 fclose(stream);
68 if(numread > 0)
69 {
70 szWP[numread] = 0L;
71 strReslt = wstring(szWP);
72 }
73 return strReslt;
74 }
75 //将当前墙纸名称写入记录文件
76 void WriteLastWallpaperName(wstring strWallpaperName)
77 {
78 FILE *stream;
79 errno_t err;
80 if( (err = fopen_s( &stream, "wallpaper.txt", "wt" )) ==0 )
81 {
82 fwrite( strWallpaperName.c_str(), sizeof( WCHAR ), strWallpaperName.length(), stream );
83 }
84 if(stream)
85 fclose(stream);
86 }
87 //判断路径是否为根路径
88 BOOL IsRoot(LPCTSTR lpszPath)
89 {
90 TCHAR szRoot[4];
91 wsprintf(szRoot,_T("%c://"),lpszPath[0]);
92 return (lstrcmp(szRoot,lpszPath)==0);
93 }
94 //查找到给定路径下的所有图片文件
95 //lpszPath:墙纸图片文件路径
96 //vecFileName:存储图片文件名的数组
97 void FindAllPicture(LPCTSTR lpszPath,vector<wstring> &vecFileName)
98 {
99 TCHAR szFind[MAX_PATH];
100 lstrcpy(szFind,lpszPath);
101 if(!IsRoot(szFind))
102 lstrcat(szFind,_T("//"));
103 lstrcat(szFind,_T("*.*")); //找所有文件
104 WIN32_FIND_DATA wfd;
105 HANDLE hFind=FindFirstFile(szFind,& wfd);
106 if(hFind==INVALID_HANDLE_VALUE) // 如果没有找到或查找失败
107 return;
108 do
109 {
110 if(wfd.cFileName[0]=='.')
111 continue; //过滤这两个目录
112 int len = _tcslen(wfd.cFileName);
113 WCHAR* szExt = _tcsninc(wfd.cFileName,len - 3);
114 if(_tcsncmp(szExt,_T("jpg"),3)!=0 && _tcsncmp(szExt,_T("bmp"),3)!=0 &&
115 _tcsncmp(szExt,_T("gif"),3)!=0)
116 continue;
117 if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
118 {
119 TCHAR szFile[MAX_PATH];
120 if(IsRoot(lpszPath))
121 wsprintf(szFile,_T("%s%s"),lpszPath,wfd.cFileName);
122 else
123 wsprintf(szFile,_T("%s//%s"),lpszPath,wfd.cFileName);
124 FindAllPicture(szFile,vecFileName); //如果找到的是目录,则进入此目录进行递归
125 }
126 else
127 {
128 TCHAR szFile[MAX_PATH];
129 if(IsRoot(lpszPath))
130 wsprintf(szFile,_T("%s%s"),lpszPath,wfd.cFileName);
131 else
132 wsprintf(szFile,_T("%s//%s"),lpszPath,wfd.cFileName);
133 vecFileName.push_back(wstring(szFile));
134 }
135 }
136 while(FindNextFile(hFind,&wfd));
137 FindClose(hFind);
138 }
139 int main(int argc, char* argv[])
140 {
141 vector<wstring> vecFileName;
142 wstring strNewWP;
143
144 CoInitialize ( NULL );
145 wstring strCurrWP = GetLastWallpaperName();
146 WCHAR wszWallpaper [MAX_PATH];
147 MultiByteToWideChar(CP_ACP, 0, argv[1], -1, wszWallpaper, MAX_PATH);
148 FindAllPicture(wszWallpaper,vecFileName);
149 if(!strCurrWP.empty())
150 {
151 vector<wstring>::iterator pos;
152 pos = find(vecFileName.begin(),vecFileName.end(),strCurrWP);
153 if(pos != vecFileName.end())
154 {
155 pos++;
156 if(pos == vecFileName.end())
157 strNewWP = vecFileName.front();
158 else
159 strNewWP = *pos;
160 }
161 else
162 strNewWP = vecFileName.front();
163 }
164 else
165 strNewWP = vecFileName.front();
166
167 if(SetWallpaper(strNewWP,WPSTYLE_CENTER))
168 WriteLastWallpaperName(strNewWP);
169 CoUninitialize();
170 return 0;
2 //
3 #pragma comment(linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" )
4 #include <stdio.h>
5 #include <tchar.h>
6 #include <windows.h>
7 #include <wininet.h>
8 #include <shlobj.h>
9 #include <iostream>
10 #include <vector>
11 #include <string>
12 #include <algorithm>
13 using namespace std;
14 //设置墙纸函数
15 //strFileName是图像文件名,支持BMP JPEG GIF等格式
16 //dwStyle是墙纸的样式
17 //WPSTYLE_CENTER 居中 0
18 //WPSTYLE_TILE 平铺 1
19 //WPSTYLE_STRETCH 拉伸 2
20 //WPSTYLE_MAX 3
21 //返回值是TRUE时墙纸设置成功,返回FALSE时失败
22 BOOL SetWallpaper(wstring strFileName, DWORD dwStyle)
23 {
24 BOOL bReslt = FALSE;
25 HRESULT hr;
26 IActiveDesktop *pActiveDesktop;
27 //创建COM接口的实例
28 hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
29 IID_IActiveDesktop, (void**)&pActiveDesktop);
30 if(SUCCEEDED(hr))
31 {
32 //设置墙纸
33 hr = pActiveDesktop->SetWallpaper(strFileName.c_str(), 0);
34 if(SUCCEEDED(hr))
35 {
36 //设置墙纸的样式
37 WALLPAPEROPT wpo;
38 wpo.dwSize = sizeof(wpo);
39 wpo.dwStyle = dwStyle;
40 hr = pActiveDesktop->SetWallpaperOptions(&wpo, 0);
41 if(SUCCEEDED(hr))
42 {
43 //应用墙纸的设置,刷新桌面
44 hr = pActiveDesktop->ApplyChanges(AD_APPLY_ALL);
45 if(SUCCEEDED(hr))
46 bReslt = TRUE;
47 }
48 }
49 //释放COM接口实例
50 pActiveDesktop->Release();
51 }
52 return bReslt;
53 }
54 //从记录文件取得上个墙纸名称
55 wstring GetLastWallpaperName()
56 {
57 wstring strReslt;
58 FILE *stream;
59 errno_t err;
60 WCHAR szWP[MAX_PATH];
61 int numread = 0;
62 if( (err = fopen_s( &stream, "wallpaper.txt", "rt" )) ==0 )
63 {
64 numread = fread( szWP, sizeof( WCHAR ), MAX_PATH, stream );
65 }
66 if(stream)
67 fclose(stream);
68 if(numread > 0)
69 {
70 szWP[numread] = 0L;
71 strReslt = wstring(szWP);
72 }
73 return strReslt;
74 }
75 //将当前墙纸名称写入记录文件
76 void WriteLastWallpaperName(wstring strWallpaperName)
77 {
78 FILE *stream;
79 errno_t err;
80 if( (err = fopen_s( &stream, "wallpaper.txt", "wt" )) ==0 )
81 {
82 fwrite( strWallpaperName.c_str(), sizeof( WCHAR ), strWallpaperName.length(), stream );
83 }
84 if(stream)
85 fclose(stream);
86 }
87 //判断路径是否为根路径
88 BOOL IsRoot(LPCTSTR lpszPath)
89 {
90 TCHAR szRoot[4];
91 wsprintf(szRoot,_T("%c://"),lpszPath[0]);
92 return (lstrcmp(szRoot,lpszPath)==0);
93 }
94 //查找到给定路径下的所有图片文件
95 //lpszPath:墙纸图片文件路径
96 //vecFileName:存储图片文件名的数组
97 void FindAllPicture(LPCTSTR lpszPath,vector<wstring> &vecFileName)
98 {
99 TCHAR szFind[MAX_PATH];
100 lstrcpy(szFind,lpszPath);
101 if(!IsRoot(szFind))
102 lstrcat(szFind,_T("//"));
103 lstrcat(szFind,_T("*.*")); //找所有文件
104 WIN32_FIND_DATA wfd;
105 HANDLE hFind=FindFirstFile(szFind,& wfd);
106 if(hFind==INVALID_HANDLE_VALUE) // 如果没有找到或查找失败
107 return;
108 do
109 {
110 if(wfd.cFileName[0]=='.')
111 continue; //过滤这两个目录
112 int len = _tcslen(wfd.cFileName);
113 WCHAR* szExt = _tcsninc(wfd.cFileName,len - 3);
114 if(_tcsncmp(szExt,_T("jpg"),3)!=0 && _tcsncmp(szExt,_T("bmp"),3)!=0 &&
115 _tcsncmp(szExt,_T("gif"),3)!=0)
116 continue;
117 if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
118 {
119 TCHAR szFile[MAX_PATH];
120 if(IsRoot(lpszPath))
121 wsprintf(szFile,_T("%s%s"),lpszPath,wfd.cFileName);
122 else
123 wsprintf(szFile,_T("%s//%s"),lpszPath,wfd.cFileName);
124 FindAllPicture(szFile,vecFileName); //如果找到的是目录,则进入此目录进行递归
125 }
126 else
127 {
128 TCHAR szFile[MAX_PATH];
129 if(IsRoot(lpszPath))
130 wsprintf(szFile,_T("%s%s"),lpszPath,wfd.cFileName);
131 else
132 wsprintf(szFile,_T("%s//%s"),lpszPath,wfd.cFileName);
133 vecFileName.push_back(wstring(szFile));
134 }
135 }
136 while(FindNextFile(hFind,&wfd));
137 FindClose(hFind);
138 }
139 int main(int argc, char* argv[])
140 {
141 vector<wstring> vecFileName;
142 wstring strNewWP;
143
144 CoInitialize ( NULL );
145 wstring strCurrWP = GetLastWallpaperName();
146 WCHAR wszWallpaper [MAX_PATH];
147 MultiByteToWideChar(CP_ACP, 0, argv[1], -1, wszWallpaper, MAX_PATH);
148 FindAllPicture(wszWallpaper,vecFileName);
149 if(!strCurrWP.empty())
150 {
151 vector<wstring>::iterator pos;
152 pos = find(vecFileName.begin(),vecFileName.end(),strCurrWP);
153 if(pos != vecFileName.end())
154 {
155 pos++;
156 if(pos == vecFileName.end())
157 strNewWP = vecFileName.front();
158 else
159 strNewWP = *pos;
160 }
161 else
162 strNewWP = vecFileName.front();
163 }
164 else
165 strNewWP = vecFileName.front();
166
167 if(SetWallpaper(strNewWP,WPSTYLE_CENTER))
168 WriteLastWallpaperName(strNewWP);
169 CoUninitialize();
170 return 0;
171 }
简单解释一下:
下面这一句使控制台程序不弹出CMD窗口。
#pragma comment(linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" )
如果使用了上面的链接预处理指令,则必须把控制台程序的主函数改为:
int main(int argc, char* argv[])
Windows下任务计划的设置方式见图示。
下载应用程序和源码。【】
相关文章:Windows XP下开源免费的自动墙纸切换(Slide Show)程序
Windows XP下开源免费的自动墙纸切换(Slide Show)程序