Powrót do strony głównej

C++ zmiana tapet Windows: WinAPI i COM

Program w C++ cyklicznie zmienia tapety i jednolity kolor pulpitu Windows. Opisano ukrywanie konsoli linkerem, konfiguracje TEST/Release, sprawdzanie bieżącego tła przez SystemParametersInfo i ustawianie przez WinAPI/COM.

Programowo zmieniamy tapety i kolor w C++ w Windows
Advertisement 728x90

Programowa zmiana tapety i tła pulpitu w C++ na Windows

Program w C++ dla Windows przełącza tło pulpitu między obrazami a jednolitym kolorem. Uruchamia się bez widocznego okna konsoli. W trybie debug okno jest widoczne do debugowania, w release i test — ukryte.

Dwa sposoby ukrycia:

  • Programowe ukrycie za pomocą GetConsoleWindow() i ShowWindow(hWnd, SW_HIDE). Okno jest tworzone i natychmiast ukrywane — powoduje to migotanie.
  • Dyrektywy linkera (zalecana metoda):
#ifndef _DEBUG
#pragma comment(linker, "/subsystem:windows")
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
#endif

Pierwsza dyrektywa kompiluje jako aplikację GUI z punktem wejścia WinMain(). Druga zachowuje main() i zapobiega tworzeniu konsoli. Brak migotania.

Google AdInline article slot

Konfiguracje kompilacji

Trzy konfiguracje w Visual Studio: Debug, Release, TEST (dziedziczy po Release).

W TEST dodano definicję preprocesora _TEST w właściwościach projektu (C/C++ → Preprocesor).

  • TEST: tapety w folderze exe jako 0.jpg...4.jpg. Uruchomienie: ChangeDesktopColor.exe X (X=0-4).
  • Release: pełne ścieżki do plików, niezależnie od lokalizacji exe.

Do debugowania TEST w Debug odkomentuj #define _TEST.

Google AdInline article slot

Określenie ścieżki exe (istotne dla 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] jest puste przy uruchamianiu z Eksploratora, dlatego GetModuleFileName.

Wybór pliku na podstawie argumentu:

Google AdInline article slot
#ifdef _TEST
    switch (*argv[1]) {
    case '0': filePath = dir.wstring() + L"\\0.jpg"; fileName = L"0.jpg"; break;
    // ... podobnie dla 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

Sprawdzenie aktualnej tapety

Pobranie bieżącego tła:

wchar_t wallFile[MAX_PATH] = { L'\0' };
SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, wallFile, 0);
wchar_t* ptr = wcsstr(wallFile, fileName.c_str());
  • Jeśli ptr == NULL: jednolity kolor lub inny plik.
  • wallFile zawiera nazwę pliku lub jest puste dla koloru.

Ustawienie tapety lub koloru

Logika przełączania:

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
}

Wybór API poprzez #define MyCOM:

  • WinAPI (SetDesktopSolidColor): podstawowa metoda.
  • COM (ChangeDesktopBackgroundColor): alternatywna.

SPIF_SENDWININICHANGE rozsyła aktualizację do wszystkich okien.

Przykłady uruchomienia w TEST:

  • ChangeDesktopColor.exe 00.jpg
  • ChangeDesktopColor.exe 9994.jpg (domyślnie)
  • ChangeDesktopColor.exe 1 20.jpg (pierwszy argument)

Praktyczne zastosowanie

Program do cyklicznej zmiany: plik → czarny kolor → plik → ...

Tapety jako ściągawki: 0.jpg — kombinacje klawiszy dla Razer NAGA X (12+12 przycisków z modyfikatorem). Szybki dostęp do makr bez rozpraszania.

Co ważne:

  • Ukrycie konsoli linkerem lepsze niż programowe — bez migotania.
  • _TEST ułatwia rozwój z lokalnymi plikami 0.jpg-4.jpg.
  • Sprawdzenie wcsstr odróżnia plik od jednolitego koloru.
  • SPIF_UPDATEINIFILE zapisuje zmiany w rejestrze.
  • Argument linii poleceń określa tapetę (0-4).

— Editorial Team

Advertisement 728x90

Czytaj dalej