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)程序