Zpět na domů

C++ změna tapety Windows: WinAPI a COM

Program v C++ cyklicky mění tapetu a spojitou barvu pracovní plochy Windows. Popsáno skrytí konzole linkerem, konfigurace TEST/Release, kontrola aktuálního pozadí přes SystemParametersInfo a nastavení přes WinAPI/COM.

Programově měníme tapetu a spojitou barvu v C++ ve Windows
Advertisement 728x90

Programmní změna tapety a pozadí plochy v C++ pro Windows

Program v C++ pro Windows mění pozadí plochy mezi obrázky a plnou barvou. Spouští se bez viditelného konzolového okna. V debug módu je okno vidět pro ladění, v release a test je skryté.

Dva přístupy ke skrytí:

  • Programové skrytí přes GetConsoleWindow() a ShowWindow(hWnd, SW_HIDE). Okno se vytvoří a hned skryje — dochází k záblesku.
  • Direktivy linkeru (preferovaný způsob):
#ifndef _DEBUG
#pragma comment(linker, "/subsystem:windows")
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
#endif

První direktiva sestaví jako GUI aplikaci s vstupním bodem WinMain(). Druhá zachová main() a zabrání vytvoření konzole. Žádný záblesk.

Google AdInline article slot

Konfigurace sestavení

Tři konfigurace ve Visual Studio: Debug, Release, TEST (dědí z Release).

V TEST je přidáno předprocesorové definice _TEST ve vlastnostech projektu (C/C++ → Předprocesor).

  • TEST: tapety v adresáři exe jako 0.jpg...4.jpg. Spuštění: ChangeDesktopColor.exe X (X=0-4).
  • Release: úplné cesty k souborům, nezávisle na umístění exe.

Pro ladění TEST v Debug odkomentovat #define _TEST.

Google AdInline article slot

Zjistění cesty exe (aktuální pro TEST):

wchar_t pathTmp[MAX_PATH] = { L'\0' };
GetModuleFileName(NULL, pathTmp, MAX_PATH);
std::filesystem::path dir = ((std::filesystem::path)pathTmp).parent_path();

argv[0] je prázdné při spuštění z Průzkumníka, proto GetModuleFileName.

Výběr souboru podle argumentu:

Google AdInline article slot
#ifdef _TEST
    switch (*argv[1]) {
    case '0': filePath = dir.wstring() + L"\\0.jpg"; fileName = L"0.jpg"; break;
    // ... podobně pro 1-4
    default: filePath = dir.wstring() + L"\\4.jpg"; fileName = L"4.jpg";
    }
#else
    switch (*argv[1]) {
    case '0': filePath = L"C:\\folder\\subfolder\\filename0.jpg"; fileName = L"filename0.jpg"; break;
    // ...
    }
#endif

Kontrola aktuální tapety

Získání aktuálního pozadí:

wchar_t wallFile[MAX_PATH] = { L'\0' };
SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, wallFile, 0);
wchar_t* ptr = wcsstr(wallFile, fileName.c_str());
  • Pokud ptr == NULL: plná barva nebo jiný soubor.
  • wallFile obsahuje název souboru nebo je prázdné pro barvu.

Nastavení tapety nebo barvy

Logika přepínání:

if (!ptr && std::filesystem::exists(filePath)) {
    BOOL result = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (void*)filePath.c_str(), 
                                        SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
} else {
    COLORREF blackColor = RGB(0, 0, 0);
#ifdef MyCOM
    HRESULT hr = ChangeDesktopBackgroundColor(blackColor);
    if (SUCCEEDED(hr)) {
        SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDWININICHANGE);
    }
#else
    if (SetDesktopSolidColor(blackColor)) {
        SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDWININICHANGE);
    }
#endif
}

Výběr API přes #define MyCOM:

  • WinAPI (SetDesktopSolidColor): hlavní metoda.
  • COM (ChangeDesktopBackgroundColor): alternativa.

SPIF_SENDWININICHANGE rozesílá aktualizaci všem oknům.

Příklady spuštění v TEST:

  • ChangeDesktopColor.exe 00.jpg
  • ChangeDesktopColor.exe 9994.jpg (výchozí)
  • ChangeDesktopColor.exe 1 20.jpg (první argument)

Praktické využití

Program pro cyklickou změnu: soubor → černá barva → soubor → ...

Tapety jako podpůrné materiály: 0.jpg — kombinace kláves pro Razer NAGA X (12+12 tlačítek s modifikátorem). Rychlý přístup k makerům bez rozptylování.

Důležité body:

  • Skrytí konzole linkerem je lepší než programové — bez záblesku.
  • _TEST usnadňuje vývoj s lokálními soubory 0.jpg-4.jpg.
  • Kontrola wcsstr odliší soubor od plné barvy.
  • SPIF_UPDATEINIFILE uloží změny do registru.
  • Argument příkazového řádku určuje tapetu (0-4).

— Editorial Team

Advertisement 728x90

Číst dál