Post

Windows, C++ | Bing Backgrounds Getter

Get Bing Wallpaper. It's a program written by C++, it will automatically download and set wallpaper for you!

Windows, C++ | Bing Backgrounds Getter

Wallpapers, Bing…

​ Have you ever tried to download wallpapers from www.bing.com? Have you ever dreamed of a fantastic background but feel bored with download wallpapers by hands! It’s a program written by C++, it will automatically download and set wallpaper for you!

My program

How does it works

​ It will download a XML file contains the API of www.bing.com, and then, I use tinyxml to parse the file to obtain the full URL-path of the daily wallpaper. Finally, the wallpaper will be download and set as the background.

Details

Platform:

  • Windows 7
  • Visual Studio 2019(Preview)
  • Old damn computer & sh*t mouse & dusty keyboard

​ What’s the local of the wallpaper? After Googling, I get this: “https://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-US”. That’s important, the full URL is contained in this file. Take a look at the label <image><url></url></image>, it’s the part of the full path, just cat "www.bing.com" with it, you will obtain the full path.

​ So, we should download the XML and try to parse it. We require URLDownloadToFile() to download remote files:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
string xml_url = "https://cn.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1";
size_t len = xml_url.length();
int nmlen = MultiByteToWideChar(CP_ACP, 0, xml_url.c_str(), len + 1, NULL, 0);
wchar_t* buffer = new wchar_t[nmlen];
MultiByteToWideChar(CP_ACP, 0, xml_url.c_str(), len + 1, buffer, nmlen);
HRESULT hr = URLDownloadToFile(NULL, buffer, _T("C:\\Program Files\\The0d0re C00per\\Bing Backgrouds\\XML\\INDEX.xml"), 0, NULL);
if (hr == S_OK)
{
    cout << "Download XML -----------------> DONE" << endl;
    get_pic_url();
}
else
{
    std::cout << "Xml download failed!Please check whether the network connection is normal!" << std::endl;
    MessageBoxA(NULL, "Xml download failed!Please check whether the network connection is normal!", "WARNING!", MB_OK);
}

​ Next, the program should know where <image><url></url></image> is and what’s in this label. I use tinyxml to make it (more about tinyxml).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
TiXmlDocument doc;
const char* xmlFile = "C:\\Program Files\\The0d0re C00per\\Bing Backgrouds\\XML\\INDEX.xml";
if (doc.LoadFile(xmlFile))
{
	cout << "Load file -----------------> DONE" << endl;
}
else 
{
    cout << "Can not parse xml!!" << endl;
    MessageBoxA(NULL, "Can not parse xml!! Please restart the program and try again!!", "WARNING!", MB_OK);
}

TiXmlElement* images = doc.RootElement();
TiXmlElement* image = images->FirstChildElement("image");

string WebPicturedomain = "http://www.bing.com";
string WebPictureUrl = "";

if (image != NULL)
    WebPictureUrl = image->FirstChildElement("url")->GetText();

string WebPictureFullpath = WebPicturedomain + WebPictureUrl;
cout << "Today Wallpaper Url Successful analysis!" << std::endl;
cout << "The address is:" << std::endl;
cout << WebPictureFullpath << std::endl;

URLDownloadToFile() again to download the wallpaper…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string pic_url = WebPictureFullpath;
size_t len0 = pic_url.length();
int nmlen0 = MultiByteToWideChar(CP_ACP, 0, pic_url.c_str(), len0 + 1, NULL, 0);
wchar_t* buffer0 = new wchar_t[nmlen0];
MultiByteToWideChar(CP_ACP, 0, pic_url.c_str(), len0 + 1, buffer0, nmlen0);
HRESULT hr0 = URLDownloadToFile(NULL, buffer0, _T("C:\\Program Files\\The0d0re C00per\\Bing Backgrouds\\PIC\\Today Wallpaper.png"), 0, NULL);
if (hr0 == S_OK)
{
    cout << "Wallpaper Successfully Download!!!" << std::endl;
}
else
{
    std::cout << "Wallpaper download failed!Please check whether the network connection is normal!" << std::endl;
    MessageBoxA(NULL, "Wallpaper download failed!Please check whether the network connection is normal!", "WARNING!", MB_OK);
}

Finally, it’s time to set wallpaper as the background!!! I wrote a function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
int ApplyWallpaper(const char* szFileDir, int displayStyle)
{
    WCHAR wsz[MAX_PATH];
    MultiByteToWideChar(
        CP_ACP,
        0,
        szFileDir,
        -1,
        wsz,
        MAX_PATH
    );
    CoInitialize(NULL);
    std::wstring x = wsz;

    DWORD dwStyle = displayStyle;
    HRESULT hr;
    IActiveDesktop* pIAD;
    hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
        IID_IActiveDesktop, (void**)&pIAD);
    if (!SUCCEEDED(hr))
    {
        int errNum = GetLastError();
        return errNum;
    }
    hr = pIAD->SetWallpaper(x.c_str(), 0);
    if (!SUCCEEDED(hr))
    {
        int errNum = GetLastError();
        return errNum;
    }
    
    WALLPAPEROPT wpo;
    wpo.dwSize = sizeof(wpo);
    wpo.dwStyle = dwStyle;
    hr = pIAD->SetWallpaperOptions(&wpo, 0);
    if (!SUCCEEDED(hr))
    {
        int errNum = GetLastError();
        return errNum;
    }
    
    hr = pIAD->ApplyChanges(AD_APPLY_ALL);
    
    if (!SUCCEEDED(hr))
    {
        int errNum = GetLastError();
        return errNum;
    }
    
    pIAD->Release();

    CoUninitialize();
    
    return TRUE;
}
/*
if (ApplyWallpaper("C:\\Program Files\\The0d0re C00per\\Bing Backgrouds\\PIC\\Today Wallpaper.png", 0))
{
	std::cout << "Wallpaper Set!!" << std::endl;
    MessageBoxA(NULL, "Wallpaper Set!!", "Bing Backgrounds Getter", MB_OK);
}
else
{
	std::cout << "Failed to Set Wallpaper!!" << std::endl;
    MessageBoxA(NULL, "Failed to Set Wallpaper!!", "WARNING!", MB_OK);
}
*/

Source code

  • You can find the source code or installer on my Github.

Linux…

—————Coming soon…

This post is licensed under CC BY 4.0 by the author.