众所周知,bing搜索网站首页每日会更新一张图片,张张漂亮(额,也有一些不合我口味的),特别适合用来做电脑壁纸。

我们想要将bing网站背景图片设置为电脑桌面背景的通常做法是:

  • 上网,搜索bing
  • 找到图片的下载链接,并下载之
  • 将图片设置为桌面背景(也有部分浏览器支持直接在网页中右击图片设置为壁纸)
  • 可能你还会删除下载下来的图片

作为一枚coder,你不会觉得麻烦嘛?至少需要三个步骤呢!

So...我就用C++语言写了一个小程序,用于获取bing网站的图片,并将其设置为桌面背景。整个过程只需要点击.exe文件,一键完成!

当然,你也可以通过本程序,窥见Windows API的些许用法,活学活用C++知识!

当然网上也存在片片断断的程序,我的部分程序也借鉴了它们的思想,在此感谢互联网和辛勤的贡献者们。

以下是程序设计的技术要点:

--------------------------------------------------------------

技术要点:

    1、获取网络地址   直接使用网络地址或下载 注意若下载下来后,要将\转换为/,当然也可以用\\
       网络地址可以从这里获取:http://cn.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1
       在返回的xml页面中(images->image->url)找到具体的图片地址(xml解析),拼接到bing域名后面构成完整地址
       注:xml解析用了TinyXml2

    2、转换图片格式(jpg->bmp),本程序中的SystemParametersInfoA函数只支持bmp
       在程序中自动转换(单单改后缀名是没有用的),转换用的程序是从网上下载的,用C语言编写而成
       考虑到需要改后缀名,那就直接下载图片好了,顺便存储之

    3、图片保存路径为C:/Users/Administrator/bingPicture/,格式为.jpg 方便以后浏览

       注意:部分用户电脑可能不存在路径C:/Users/Administrator/,造成程序无法执行,可以直接在C盘根目录下创建路径,如C:/bingPicture/
       注意不保存转换后的bmp格式图片(设置背景后即删除),因为体积较大
       判断文件夹是否存在,若不存在,则自动创建文件夹

    4、注意本程序获取的图片尺寸是1366x768,若你的屏幕分辨率为1920x1080,还需要对Xml解析出来的图片Url地址进行字符串替换(将1366x768换成1920x1080即可)

       前提:针对1920x1080尺寸的图片地址存在

    5、若此程序若在国际网络下运行,获取的就是国际版bing壁纸;若在国内网络下运行,获取的就是中国版bing壁纸。因此在同一天内,在不同网络环境下获取的图片可能不同

*未实现的功能*:
    1、获取每日壁纸的故事(利用bing故事接口) ,更新壁纸后显示在执行框中

    2、开机自启动,并隐藏到托盘中(为减少CPU占用并增加趣味性,设置为开机自动启动,提示网络连接,并输入"go"才执行功能)
       电脑若未关机,则在24:00自动启动,更换背景

    3、软件自动更新版本功能

--------------------------------------------------------------

程序在文章后面提供,源码已注释很详细,不再赘述。

注意,使用程序之前,务必看以下注意事项:

--------------------------------------------------------------

请注意:
    1、本软件使用Qt开发,您也可以将文件加入自己的工程,使用其他IDE开发
         需要注意的一点是,本软件需要加入URLMON.DLL(源码包中有)

2、本软件开源(源码位于xiaoxi666的博客园以及github,不对其他地址给出的链接负责),仅用于学习交流,请勿用于商业用途

3、为防止软件被加入恶意功能,不提供可执行文件,若需使用请重新编译,编译器需要支持c++11

4、本软件程序中内含删除临时文件功能,请在更改前仔细确认,避免路径错误而删除其他重要文件

--------------------------------------------------------------

然而许多小伙伴要体验效果,我就一并把可执行文件放出来吧(请勿随意传播.exe文件防止有人添加恶意功能。当然源码开放可共享)

下载区:

但一定要注意核对文件校验码(以保证安全):

  • 可执行文件压缩包WallPaper校验码

    MD5: 48173BA7DCF2120F2822226A5D4A90CF
           SHA1: CEB0ED570AF613EC3829AC8FDE4F8C50DDEF4101

  • 可执行文件WallPaper_1366x768_Common校验码(此版本用于1366x768分辨率)

    MD5: ACDA8E5E4CF0B2916254B233D1243FD3
       SHA1: 6041C813DC8E2AE29EA8675EF279CFC0E7921D53

  • 可执行文件WallPaper_1920x1080_Common校验码(此版本用于1920x1080分辨率)

    MD5: 474570808A56EFDC7B589F605D08C5B6
        SHA1: B78921AD655B35F079076904A22F1A0E5122EB7F

为方便浏览,贴出主要源程序:

main.cpp文件

  1 //main.cpp
2 /******************windows桌面背景更换C++程序***********************************************************
3 功能:获取每日bing搜索主页图片,设置为当日桌面壁纸。并将其下载保存至本地文件夹方便以后浏览
4 作者:xiaoxi666
5 日期:2017/03/12
6
7 技术要点:
8 1、获取网络地址 直接使用网络地址或下载 注意若下载下来后,要将\转换为/,当然也可以用\\
9 网络地址可以从这里获取:http://cn.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1
10 在返回 的xml页面中(images->image->url)找到具体的图片地址(xml解析),拼接到bing域名后面,构成完整地址
11 注:xml解析用了TinyXml2
12
13 2、转换图片格式(jpg->bmp),本程序中的SystemParametersInfoA函数只支持bmp
14 在程序中自动转换(单单改后缀名是没有用的),转换用的程序是从网上下载的,用C语言编写而成
15 考虑到需要改后缀名,那就直接下载图片好了,顺便存储之
16
17 3、图片保存路径为C:\bingPicture\,格式为.jpg 方便以后浏览
18 注意不保存转换后的bmp格式图片(设置背景后即删除),因为体积较大
19 判断文件夹是否存在,若不存在,则自动创建文件夹
20
21 *未实现的功能*:
22 ***获取每日壁纸的故事(利用bing故事接口) ,更新壁纸后显示在执行框中
23
24 ***开机自启动,并隐藏到托盘中(为减少CPU占用并增加趣味性,设置为开机自动启动,提示网络连接,并输入"go"才执行功能)
25 电脑若未关机,则在24:00自动启动,更换背景
26
27 ***软件自动更新版本功能
28
29 ******************************************************************************************************/
30
31 #include <iostream> //输入输出
32 #include <cstring> //文件命名处理需要用字符串
33 #include <windows.h> //调用操作系统各种API
34 #include <ctime> //获取时间,各种文件命名
35 #include <UrlMon.h> //包含提供下载服务的API
36 #include "tinyxml2.h" //解析XML
37 #include <io.h> //判断文件夹是否存在
38 #include <direct.h> //创建文件夹
39 extern "C"
40 {
41 #include "jpeg.h" //转换图片格式jpg->bmp 转换格式的程序使用C语言写的
42 }
43
44 //创建本地bingPicture路径和Tmp路径
45 void createDir()
46 {
47 //本地bingPicture路径
48 std::string LocalFolder="C:/bingPicture/";
49
50 if(0!=access(LocalFolder.c_str(),0)) //判断文件夹是否存在,若不存在则创建
51 if(0!=mkdir(LocalFolder.c_str()))
52 std::cout<<"创建文件夹bingPicture失败!"<<std::endl;
53 else
54 std::cout<<"创建文件夹bingPicture成功!"<<std::endl;
55 else
56 std::cout<<"文件夹bingPicture已存在!"<<std::endl;
57
58 //本地Tmp路径
59 std::string LocalXmlFolder="C:/bingPicture/Tmp/";
60
61 if(0!=access(LocalXmlFolder.c_str(),0)) //判断文件夹是否存在,若不存在则创建
62 if(0!=mkdir(LocalXmlFolder.c_str()))
63 std::cout<<"创建临时文件夹Tmp失败!"<<std::endl;
64 else
65 std::cout<<"创建临时文件夹Tmp成功!"<<std::endl;
66 else
67 std::cout<<"临时文件夹Tmp已存在!"<<std::endl;
68
69 }
70
71 /**************************************************************************************
72 首先明白一个概念,即string替换所有字符串,将"12212"这个字符串的所有"12"都替换成"21",结果是什么?
73 可以是22211,也可以是21221,有时候应用的场景不同,就会希望得到不同的结果,所以这两种答案都做了实现。
74 **************************************************************************************/
75 //替换字符串方法1(完全轮询,替换一次后接着再次扫描,因为替换一次后可能又出现了满足替换条件的字符串)
76 std::string & replace_all(std::string& str,const std::string& old_value,const std::string& new_value)
77 {
78 while(true) {
79 std::string::size_type pos(0);
80 if((pos=str.find(old_value))!=std::string::npos)
81 str.replace(pos,old_value.length(),new_value);
82 else
83 break;
84 }
85 return str;
86 }
87
88 //替换字符串方法2(只替换一次) 本项目中,只替换\为/用方法2即可
89 std::string & replace_all_distinct(std::string& str,const std::string& old_value,const std::string& new_value)
90 {
91 for(std::string::size_type pos(0); pos!=std::string::npos; pos+=new_value.length())
92 {
93 if((pos=str.find(old_value,pos))!=std::string::npos)
94 str.replace(pos,old_value.length(),new_value);
95 else break;
96 }
97 return str;
98 }
99
100 //获取年月日(命名用)
101 std::string getYearMonthDay()
102 {
103 time_t timer;
104 time(&timer);
105 tm* t_tm = localtime(&timer);
106
107 std::string Year=std::to_string(t_tm->tm_year+1900);
108 std::string Month=std::to_string(t_tm->tm_mon+1);
109 std::string Day=std::to_string(t_tm->tm_mday);
110 std::string PictureName=Year+"_"+Month+"_"+Day;
111
112 return PictureName;
113 }
114
115 //获取图片的Xml并解析图片的url路径
116 std::string getPicTureXmlAndUrl()
117 {
118 //网络上的XML路径
119 std::string WebXmlpath ="http://cn.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1";
120 //本地Xml路径
121 std::string LocalXmlFolder="C:/bingPicture/Tmp/";
122 std::string LocalXmleach=getYearMonthDay();
123 std::string LocalXmlFullpath=LocalXmlFolder+LocalXmleach+".xml";
124
125 if(URLDownloadToFileA(NULL,
126 WebXmlpath.c_str(),
127 LocalXmlFullpath.c_str(),
128 0,
129 NULL)
130 ==S_OK)
131 {
132 std::cout<<"Xml下载成功!即将解析今日壁纸Url!"<<std::endl;
133
134 /***************下面开始解析xml中的url路径*******************/
135 tinyxml2::XMLDocument doc;
136 if(tinyxml2::XML_SUCCESS != doc.LoadFile(LocalXmlFullpath.c_str()))
137 std::cout<<"读取Xml文件异常!"<<std::endl;
138 tinyxml2::XMLElement *images=doc.RootElement();
139 tinyxml2::XMLElement *image =images->FirstChildElement("image");
140
141 //图片Url
142 std::string WebPicturedomain="http://cn.bing.com";
143 std::string WebPictureUrl="";
144
145 if(image!=NULL)
146 WebPictureUrl=image->FirstChildElement("url")->GetText();
147
148 std::string WebPictureFullpath1366x768 =WebPicturedomain+WebPictureUrl;
149 std::cout<<"今日壁纸Url解析成功!"<<std::endl;
150 /*********************************************************/
151 return WebPictureFullpath1366x768;
152 // //将1366x768换成1920x1080
153 // std::string WebPictureFullpath1920x1080 =replace_all_distinct(WebPictureFullpath1366x768,"1366x768","1920x1080");
154
155 // return WebPictureFullpath1920x1080;
156 }
157 else
158 {
159 std::cout<<"Xml下载失败!无法获取图片Url!请检查网络连接是否正常!"<<std::endl;
160 return "error";
161 }
162
163 }
164
165 //从网络上下载图片并存储到本地
166 std::string getPicture(std::string WebFullpath)
167 {
168 //本地存储路径
169 std::string LocalFolder="C:/bingPicture/";
170 std::string Localeach=getYearMonthDay();
171 std::string LocalFullpath=LocalFolder+Localeach+".jpg";
172
173 if(URLDownloadToFileA(NULL,
174 WebFullpath.c_str(),
175 LocalFullpath.c_str(),
176 0,
177 NULL)
178 ==S_OK)
179 {
180 std::cout<<"今日壁纸下载成功!"<<std::endl;
181
182 /***************下面转换图片格式jpg->bmp******************/
183 //临时文件夹Tmp路径
184 std::string TmpFolder="C:/bingPicture/Tmp/";
185 //.bmp图片路径
186 std::string bmpFolder=TmpFolder+getYearMonthDay()+".bmp";
187 LoadJpegFile(const_cast<char *>(LocalFullpath.c_str()),const_cast<char *>(bmpFolder.c_str()));
188 /*******************************************************/
189 return bmpFolder;
190 }
191 else
192 {
193 std::cout<<"壁纸下载失败!请检查网络连接是否正常!"<<std::endl;
194 return "error";
195 }
196 }
197
198 //改变桌面背景成功后,删除bmp文件和xml文件(只保留jpg文件),此步骤需要小心,避免删除错误路径下的内容
199 void deleteBmpAndXml()
200 {
201 //临时文件夹Tmp路径
202 std::string TmpFolder="C:/bingPicture/Tmp/";
203 //.bmp图片路径
204 std::string bmpFolder=TmpFolder+getYearMonthDay()+".bmp";
205 //xml文件路径
206 std::string xmlFolder=TmpFolder+getYearMonthDay()+".xml";
207
208 if(0==access("C:/bingPicture/Tmp/",0)) //判断文件夹是否存在,若存在则删除
209 {
210 //删除bmp图片
211 if(0==access(bmpFolder.c_str(),0))
212 {
213 if(0==remove(bmpFolder.c_str()))
214 std::cout<<"删除临时bmp格式图片成功!"<<std::endl;
215 else
216 std::cout<<"删除临时bmp格式图片失败!"<<std::endl;
217 }
218 else
219 std::cout<<"临时bmp格式图片不存在!"<<std::endl;
220
221 //删除xml文件
222 if(0==access(xmlFolder.c_str(),0))
223 {
224 if(0==remove(xmlFolder.c_str()))
225 std::cout<<"删除xml文件成功!"<<std::endl;
226 else
227 std::cout<<"删除xml文件失败!"<<std::endl;
228 }
229 else
230 std::cout<<"xml文件不存在!"<<std::endl;
231
232 //删除Tmp文件夹(注意此函数只能删除空文件夹,因此要先删除文件夹中的文件)
233 if(0==rmdir(TmpFolder.c_str()))
234 std::cout<<"临时文件夹Tmp已删除!"<<std::endl;
235 else
236 std::cout<<"临时文件夹Tmp删除失败!"<<std::endl;
237 }
238 else
239 std::cout<<"临时文件夹Tmp不存在!"<<std::endl;
240
241 }
242
243 //改变桌面背景(PictureFullpath:图片完整路径)
244 void changePicture(std::string PictureFullpath)
245 {
246 bool result=false;
247 result=SystemParametersInfoA(SPI_SETDESKWALLPAPER,
248 0,
249 (PVOID)PictureFullpath.c_str(),
250 0);
251 if(result==false)
252 {
253 std::cout<<"今日壁纸更新失败!请联系开发人员!"<<std::endl;
254 }
255
256 else
257 {
258 SystemParametersInfoA(SPI_SETDESKWALLPAPER,
259 0,
260 (PVOID)PictureFullpath.c_str(),
261 SPIF_SENDCHANGE);
262 //deleteBmpAndXml(); //windows8及其以上会变成黑色,把这条语句放到main最后面就没问题,具体原因未知
263 system("cls");
264 std::cout<<"version:1.0.0 (Author:xiaoxi666)"<<std::endl<<std::endl;
265 std::cout<<"今日壁纸更新成功!"<<std::endl<<std::endl;
266 std::cout<<"美好的一天开始啦!用心享受吧!"<<std::endl<<std::endl;
267 }
268 }
269
270 int main()
271 {
272 std::string startOrder="";
273 std::cout<<"嗨!小伙伴!你的贴心壁纸小助手已启动!将为你设置今日壁纸哦!"<<std::endl<<std::endl;
274 std::cout<<"请确保电脑网络连接状况良好,准备好后输入go"<<std::endl<<std::endl;
275 std::cout<<"请输入指令: ";
276 std::cin>>startOrder;
277 while("go"!=startOrder)
278 {
279 std::cout<<"哎呀输错了呢,重新输入吧: ";
280 std::cin>>startOrder;
281 }
282 if("go"==startOrder)
283 {
284 createDir();
285 changePicture(getPicture(getPicTureXmlAndUrl()));
286 }
287
288 /*******************************以下为个性化字幕输出,与程序核心功能无关************************/
289 std::string umua0=" ** ** ******** ******* ******* *** *** ";
290 std::string umua1=" ** ** ******** ******* ******* *** *** ";
291 std::string umua2=" ** ** ** ** ** ** *** ** *** *** ";
292 std::string umua3=" ** ** ** ** ** ** *** ** ** ** ";
293 std::string umua4=" ********* ******** ******* ******* * * ";
294 std::string umua5=" ********* ******** ******* ** ** ";
295 std::string umua6=" ** ** ** ** ** ** ** ";
296 std::string umua7=" ** ** ** ** ** ** ** ";
297 std::string umua8=" ** ** ** ** ** ** ** ";
298 std::string umua9=" ** ** ** ** ** ** ** ";
299
300 #define mua(n) std::cout<<umua##n<<std::endl;
301 std::cout<<std::endl<<std::endl;
302 mua(0);mua(1);mua(2);mua(3);mua(4);mua(5);mua(6);mua(7);mua(8);mua(9);
303 std::cout<<std::endl<<std::endl<<std::endl;
304 system("pause");
305 /******************************************************************************************/
306 deleteBmpAndXml();
307 return 0;
308 }

图片格式转换程序(这个是网上下载的C源码,我改了一下接口,在此感谢)

jpeg.h

 

jpeg2bmp.c

 

xml解析,我用的是TinyXml2开源库,这个就不贴源码了。

关于Qt项目图标制作

我用的Qt版本是4.8.5。

步骤如下:

  1. 在Qt工程目录下新建一个文本文件,并将其名称改为 *.rc (名字任取)
  2. 将你的图标文件.ico添加到项目中
  3. 打开该 rc 文件,在该rc文件里面加入以下一行文本(将文本中的*换成你的图标的名字):

    IDI_ICON   ICON    DISCARDABLE     "*.ico" 
  4. 在项目文件.pro中加入以下文本(将*换成你的rc文件名字):

     RC_FILE = \
             *.rc

5. 重新编译工程即可

   

关于Qt项目的发布

Qt项目发布最麻烦的就是动态依赖库,常用的工具是hap-depends,它可以查看软件的依赖库(*.dll),直接用它打开你的.exe文件,查看缺失哪些.dll文件,找到它们后和exe放在相同目录即可。

当然,发布之前需要经过多个平台的测试。

最后祝大家生活愉快!

『注:本文来自博客园“小溪的博客”,若非声明均为原创内容,请勿用于商业用途,转载请注明出处http://www.cnblogs.com/xiaoxi666/』
 
http://www.cnblogs.com/xiaoxi666/p/6544478.html

获取bing图片并自动设置为电脑桌面背景(使用 URLDownloadToFile API函数)的更多相关文章

  1. 获取bing图片并自动设置为电脑桌面背景(C++完整开源程序)

    众所周知,bing搜索网站首页每日会更新一张图片,张张漂亮(额,也有一些不合我口味的),特别适合用来做电脑壁纸. 我们想要将bing网站背景图片设置为电脑桌面背景的通常做法是: 上网,搜索bing 找 ...

  2. 【开源程序(C++)】获取bing图片并自动设置为电脑桌面背景

    众所周知,bing搜索网站首页每日会更新一张图片,张张漂亮(额,也有一些不合我口味的),特别适合用来做电脑壁纸. 我们想要将bing网站背景图片设置为电脑桌面背景的通常做法是: 上网,搜索bing 找 ...

  3. UGUI之导入图片之前自动设置图片打包的 tag

    之前一直在用的是NGUI,最近不知怎么突然兴趣来潮,想学习一下UGUI,毕竟,现在纵观Unity的市场,完全是UGUI的天下,NGUI已经渐渐退隐江湖,哈哈哈... 先来记录下,在图片资源导入到Uni ...

  4. Wince 6.0获取设备的分辨率 自动设置窗体位置

    调用微软提供给wince的API  “coredll.dll” [DllImport("coredll.dll")] public static extern int GetSys ...

  5. Qt设置系统时间(使用SetSystemTime API函数)

    大家都知道Qt中有QDateTime等有关时间与日期的类,类中包含很多成员函数,可以很方便的实现有关时间与日期的操作,比如:想要获得系统当前的时间与日期,可以调用currentDateTime();  ...

  6. Unity3D 导入贴图、模型等资源文件时自动设置参数

    脚本继承至AssetPostprocessor, 存放在Editor目录下! using UnityEngine; using System.Collections; using UnityEdito ...

  7. 使用CSS设置边框和背景

    一.设置边框 1.边框样式 属性 说明 border-width 设置边框的宽度 boder-style 设置边框的样式 border-color 设置边框的颜色 a.border-width属性 自 ...

  8. 获取bing.com的图片并在gnome3中设置自动切换

    发现 bing.com 上的图片很好看,因此打算每天把 bing.com 的图片下载下来,用作桌面. 需要做的是两个部分,爬取图片到目录和设置目录图片为桌面背景并可以自动切换. 第一部分,下载图片,使 ...

  9. 获取Bing每日图片API接口

    bing图片每日更新,对于这一点感觉挺不错的,如果能够把bing每日图片作为博客背景是不是很不错呢?首先我们进入Bing首页,会发现自动转到中国版.不过这没关系,中国版更符合国情,速度也比国际版快一些 ...

随机推荐

  1. erlang一些参考资源

    1. erlang非业余研究 http://blog.yufeng.info/ 2.code.wang http://www.cnblogs.com/codew/ 3.码农生涯 http://www. ...

  2. spring mvc redirect 重定向 跳转并传递参数

    在项目中做form表单功能提交时,防止用户客户端后退或者刷新时重复提交问题,需要在服务端进行重定向跳转,具体跳转方式有以下几种方式: 公用代码: @RequestMapping(value=" ...

  3. [React Router v4] Use the React Router v4 Link Component for Navigation Between Routes

    If you’ve created several Routes within your application, you will also want to be able to navigate ...

  4. JAVA 安装JDK注意事项

    在JAVA jdk安装的时候,文件夹名称最好不要有中文,有逗号,有下划线,空格等问题.这样easy出错,比方以下几个安装路径easy出错    java文件夹/jdk1.6_x86/    这样的就是 ...

  5. css+html+js实现多级下拉和弹出菜单

    本文将使用css+html+js实现横向菜单.具有多级弹出菜单下拉. 首先我们来看看效果图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgy ...

  6. UITableView的一些事1

    方法1: _tableview = [[UITableView alloc]initWithFrame:CGRectMake(0, 0,self.view.bounds.size.width,self ...

  7. erlang中如何调试程序

    学习一门语言,当学习那些基本语法的时候,我们常常会忽略它的程序调试,当程序稍微复杂一点的时候,我们不能保证程序的完全正确,我们会为其发愁,这时,程序的调试就变得相当重要了.    在erlang环境搭 ...

  8. ZooKeeper 分布式锁实现原理

    原理 进程需要访问共享数据时, 就在"/locks"节点下创建一个sequence类型的子节点, 称为thisPath. 当thisPath在所有子节点中最小时, 说明该进程获得了 ...

  9. 二叉苹果树 - 二叉树树型DP

    传送门 中文题面: 题目描述 有一棵苹果树,如果树枝有分叉,一定是分 2 叉(就是说没有只有 1 个儿子的结点,这棵树共有N 个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一 ...

  10. WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush)

    原文:WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush) 前面我们介绍到,Path对象表示一个用直线或者曲线连接的图形,我们可以使用Path.Data ...