0

Is there any quick way to change a windows wallpaper in C++? I'm trying to animate a wallpaper and am going through a directory of images and setting the wallpaper to an image every few milliseconds, problem is, even when running on a thread, there is sometimes a time gap of a few seconds between wallpaper changes? How do I fix this? Am I doing something wrong? Here's my code:

#include <windows.h>
#include <string>
#include <iostream>
#include <chrono>
#include <thread>
#include <cstdlib>
#include <filesystem>

namespace fs = std::filesystem;
using namespace std;

void thinggg()
{
    cout << "Directory(0) or Files(1)?\n";
    int choice;
    cin >> choice;
    int num = 0;
    string* images;

    if (choice == 1)
    {
        cout << "How many images?\n";
        cin >> num;
        cin.ignore();
        images = new string[num];
        for (int i = 0; i < num; i++)
        {
            string loc;
            cout << i + 1 << ": ";
            getline(cin, loc);
            images[i] = loc;
        }
    }
    else
    {
        cin.ignore();

        string loc;
        cout << "Enter folder location: ";
        getline(cin, loc);

        // there is probably a much better to do this
        for (const auto& entry : fs::directory_iterator(loc))
        {
            num++;
        }
        images = new string[num];
        num = 0;
        for (const auto& entry : fs::directory_iterator(loc))
        {
            string path = entry.path().string();
            if (path.find("png") != string::npos || path.find("jpg") != string::npos || path.find("bmp") != string::npos)
            {
                images[num] = path;
            }
            num++;
        }
    }

    int intervals;
    cout << "Enter FPS: ";
    cin >> intervals;
    cin.ignore();
    intervals = 1000 / intervals;

    int i = 0;
    while (true)
    {
        wstring loc = wstring(images[i].begin(), images[i].end());
        const wchar_t* a = loc.c_str();
        SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)a, SPIF_SENDCHANGE);
        i++;
        if (i == num) i = 0;
        this_thread::sleep_for(chrono::milliseconds(intervals));
    }
}

int main()
{
    thread t(thinggg);
    t.join();
    cout << "quit?" << endl;
    int a;
    cin >> a;
    if (a == 1)
    {
        t.native_handle();
        return 0;
    }
}
  • 1
    The OS wallpaper won't animate that quickly. You'll have to use a different technique, such as a window behind everything (except not behind the desktop), wherein you do your animation. – Eljay May 29 '22 at 16:55
  • Unrelated: When you need to `ignore`, it's better to place the `ignore` after the IO transaction that left the unwanted data in the stream than before another operation that needs the garbage gone. 1) it keeps the cause and effect close to one another and makes the code easier to read. 2) sooner or later you'll find or make a case that allows the `ignore` to be reached without garbage in the stream and accidentally discard data you needed to process. – user4581301 May 29 '22 at 17:53

0 Answers0