0

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";
}
Eric M
  • 1,027
  • 2
  • 8
  • 21
  • 3
    Looks like there is [COM Interface](https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-iactivedesktop-setwallpaperoptions) to do that. Might help or not :-) – Christian.K Sep 23 '21 at 05:30
  • Wow. This is really a case of my not know what to search for. Once I looked for IActiveDesktop I found tonnes of docs and examples. – Eric M Sep 23 '21 at 05:41
  • Win95 did not have those interfaces, you would just manually write to the registry first IIRC (stretch was maybe not supported yet?). – Anders Sep 25 '21 at 18:54

1 Answers1

2

Try IDesktopWallpaper interface and IActiveDesktop interfaces.

Create objects for them by creating CLSID_DesktopWallpaper and CLSID_ActiveDesktopobjects.

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79