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()iShowWindow(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.
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.
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:
#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. wallFilezawiera 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 0→0.jpgChangeDesktopColor.exe 999→4.jpg(domyślnie)ChangeDesktopColor.exe 1 2→0.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.
_TESTułatwia rozwój z lokalnymi plikami0.jpg-4.jpg.- Sprawdzenie
wcsstrodróżnia plik od jednolitego koloru. SPIF_UPDATEINIFILEzapisuje zmiany w rejestrze.- Argument linii poleceń określa tapetę (0-4).
— Editorial Team
Brak komentarzy.