How does one tell Windows 10 to tile, center, or stretch desktop wallpaper using WIN32 C/C++ API?

802 views Asked by At

Goal: using C++, the Win32 SDK and Visual Studio 2019 to set the desktop wallpaper to be centered or tiled or stretched.

One can use SystemParametersInfo() to change the wallpaper. No problem at all.

Problem is telling the system to tile or center or stretch the wallpaper image.

Reading on the web, whether the wallpaper image is centered, tiled or stretched depends on a pair of registry entries:

HKCU\Control Panel\Desktop\TileWallpaper
HKCU\Control Panel\Desktop\WallpaperStyle

MS' WIN32 docs tell how to change the image but I can't find anything describing how to change the layout.

I have the following code. It is a console app project, the functions ripped out of my larger MFC app, thus the function names. This project's character set is set to Unicode, thus my use of W functions.

It does change the wallpaper image, but the wallpaper is always tiled, regardless of which of the onWallpaper___() functions are called.

Windows seems to completely ignore the registry changes. I have verified that my code does indeed change the registry entries' values.

Question: How does one tell Windows 10 to tile, center, or stretch desktop wallpaper using WIN32 C/C++ API?

Question: Are there different registry entries that should be used?

#include <Windows.h>
#include <iostream>
#include <string>
#include <cassert>

const int CENTERED = 0;
const int TILED = 1;
const int STRETCHED = 2;


void set_wallpaper_registry_keys(int discriminant) {
    BOOL rtn;
    HKEY hKey;
    DWORD TileWallpaper = 0;
    DWORD WallpaperStyle = 0;
    switch (discriminant) {
        case CENTERED: {
            TileWallpaper = 0;
            WallpaperStyle = 1;     // some sources say use 6, makes no difference.
        }
        break;
        case TILED: {
            TileWallpaper = 1;
            WallpaperStyle = 0;
        }
        break;
        case STRETCHED: {
            TileWallpaper = 0;
            WallpaperStyle = 2;
        }
        break;
        default: {
            assert(false);
        }
        break;
    }
    std::wstring key_name(L"Control Panel\\Desktop");
    rtn = RegOpenKeyEx(HKEY_CURRENT_USER, key_name.c_str(), 0, KEY_ALL_ACCESS, &hKey);
    assert(rtn == ERROR_SUCCESS);
    rtn = RegSetValueEx(hKey, L"TileWallpaper",  0, REG_DWORD, (BYTE *)&TileWallpaper,  sizeof(DWORD));
    assert(rtn == ERROR_SUCCESS);
    rtn = RegSetValueEx(hKey, L"WallpaperStyle", 0, REG_DWORD, (BYTE *)&WallpaperStyle, sizeof(DWORD));
    assert(rtn == ERROR_SUCCESS);
    rtn = RegFlushKey(hKey);
    assert(rtn == ERROR_SUCCESS);
    rtn = RegCloseKey(hKey);
    assert(rtn == ERROR_SUCCESS);
}


void OnWallpaperCentered() {
    BOOL rtn;
    set_wallpaper_registry_keys(CENTERED);
    // set current image as wallpaper: SPI_SETDESKWALLPAPER
    std::wstring fn = L"c:\\tmp\\stars.jpg";
    rtn = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (void *) (fn.c_str()), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
    assert(rtn == TRUE);
}


void OnWallpaperTiled() {
    // TODO: Add your command handler code here
    BOOL rtn;
    set_wallpaper_registry_keys(TILED);
    std::wstring fn = L"c:\\tmp\\snail.jpg";
    rtn = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (void *) (fn.c_str()), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
    assert(rtn == TRUE);
}


void OnWallpaperStretched() {
    // TODO: Add your command handler code here
    BOOL rtn;
    set_wallpaper_registry_keys(STRETCHED);
    std::wstring fn = L"c:\\tmp\\civ4.jpg";
    rtn = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (void*) (fn.c_str()), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
    assert(rtn == TRUE);
}


int main() {
    //OnWallpaperTiled();     // Tiles the wallpaper
    OnWallpaperCentered();    // Tiles the wallpaper as well
    //OnWallpaperStretched(); // Tiles the wallpaper too
    std::cout << "Hello World!\n";
}
1

There are 1 answers

0
Alex Guteniev On BEST ANSWER

Try IDesktopWallpaper interface and IActiveDesktop interfaces.

Create objects for them by creating CLSID_DesktopWallpaper and CLSID_ActiveDesktopobjects.