Desktop-Hintergrund und Farbe in C++ unter Windows programmgesteuert wechseln
Dieses C++-Programm für Windows wechselt den Desktop-Hintergrund zwischen Bildern und einer einheitlichen Farbe. Es läuft ohne sichtbares Konsolenfenster. Im Debug-Modus wird das Fenster für Fehlersuche angezeigt; in Release- und Test-Builds bleibt es verborgen.
Zwei Möglichkeiten, die Konsole zu verstecken:
- Programmgesteuertes Verstecken mit
GetConsoleWindow()undShowWindow(hWnd, SW_HIDE). Das Fenster blitzt kurz auf, bevor es verschwindet.
- Linker-Direktiven (empfohlener Ansatz):
#ifndef _DEBUG
#pragma comment(linker, "/subsystem:windows")
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
#endif
Die erste Direktive baut es als GUI-App mit WinMain()-Einstiegspunkt. Die zweite behält main() bei, überspringt aber die Konsolenerstellung. Kein Blitzen.
Build-Konfigurationen
Drei Visual-Studio-Konfigurationen: Debug, Release, TEST (erbt von Release).
TEST fügt die Präprozessor-Definition _TEST in den Projekteigenschaften (C/C++ → Präprozessor) hinzu.
- TEST: Bilder im EXE-Ordner als
0.jpg...4.jpg. Ausführen:ChangeDesktopColor.exe X(X=0-4). - Release: Verwendet vollständige Dateipfade, unabhängig vom EXE-Standort.
Für TEST-Debugging in Debug: #define _TEST auskommentieren.
EXE-Pfad ermitteln (wichtig für 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] ist leer, wenn aus dem Explorer gestartet, daher GetModuleFileName nutzen.
Datei per Argument wählen:
#ifdef _TEST
switch (*argv[1]) {
case '0': filePath = dir.wstring() + L"\\0.jpg"; fileName = L"0.jpg"; break;
// ... ähnlich für 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
Aktuellen Hintergrund prüfen
Aktuellen Hintergrund abrufen:
wchar_t wallFile[MAX_PATH] = { L'\0' };
SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, wallFile, 0);
wchar_t* ptr = wcsstr(wallFile, fileName.c_str());
- Wenn
ptr == NULL: Einheitliche Farbe oder andere Datei. wallFileenthält den Dateinamen oder ist leer bei einheitlicher Farbe.
Hintergrund oder Farbe setzen
Wechsel-Logik:
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
}
API per #define MyCOM wählen:
- WinAPI (
SetDesktopSolidColor): Primäre Methode. - COM (
ChangeDesktopBackgroundColor): Alternative.
SPIF_SENDWININICHANGE verteilt die Aktualisierung an alle Fenster.
TEST-Beispiele:
ChangeDesktopColor.exe 0→0.jpgChangeDesktopColor.exe 999→4.jpg(Standard)ChangeDesktopColor.exe 1 2→0.jpg(erstes Argument)
Praktische Anwendungen
Ideal zum Zyklus von Hintergründen: Bild → Schwarz → Bild → ...
Tapeten als Cheatsheets nutzen: 0.jpg zeigt Tastenkombos für Razer NAGA X (12+12 Tasten mit Modifikator). Schneller Makro-Zugriff ohne Fokusverlust.
Wichtige Erkenntnisse:
- Linker-Verstecken schlägt Programmgesteuertes – kein Blitzen.
_TESTvereinfacht Entwicklung mit lokalen0.jpg-4.jpg-Dateien.wcsstr-Prüfung unterscheidet Datei von einheitlicher Farbe.SPIF_UPDATEINIFILEspeichert im Registry.- Kommandozeilen-Argument wählt Tapete (0-4).
— Editorial Team
Noch keine Kommentare.