Cambiar fondos y colores de escritorio en C++ en Windows
Este programa en C++ para Windows alterna el fondo de escritorio entre imágenes y un color sólido. Se ejecuta sin ventana de consola visible. En modo debug, la ventana aparece para depuración; en release y TEST, queda oculta.
Dos formas de ocultar la consola:
- Ocultación programática con
GetConsoleWindow()yShowWindow(hWnd, SW_HIDE). La ventana parpadea brevemente antes de ocultarse.
- Directivas del enlazador (método recomendado):
#ifndef _DEBUG
#pragma comment(linker, "/subsystem:windows")
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
#endif
La primera directiva lo compila como app GUI con punto de entrada WinMain(). La segunda mantiene main() pero omite la creación de consola. Sin parpadeo.
Configuraciones de compilación
Tres configuraciones en Visual Studio: Debug, Release, TEST (hereda de Release).
TEST añade la definición _TEST en propiedades del proyecto (C/C++ → Preprocesador).
- TEST: Imágenes en la carpeta del exe como
0.jpg...4.jpg. Ejecutar:ChangeDesktopColor.exe X(X=0-4). - Release: Usa rutas completas, independientemente de la ubicación del exe.
Para depurar TEST en Debug, descomenta #define _TEST.
Obtener ruta del exe (clave para 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] está vacío al lanzarlo desde el Explorador, por eso se usa GetModuleFileName.
Seleccionar archivo por argumento:
#ifdef _TEST
switch (*argv[1]) {
case '0': filePath = dir.wstring() + L"\\0.jpg"; fileName = L"0.jpg"; break;
// ... similar para 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
Verificar el fondo actual
Obtener fondo actual:
wchar_t wallFile[MAX_PATH] = { L'\0' };
SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, wallFile, 0);
wchar_t* ptr = wcsstr(wallFile, fileName.c_str());
- Si
ptr == NULL: color sólido u otro archivo. wallFilecontiene el nombre del archivo o está vacío para color sólido.
Establecer fondo o color
Lógica de alternancia:
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
}
Elegir API con #define MyCOM:
- WinAPI (
SetDesktopSolidColor): método principal. - COM (
ChangeDesktopBackgroundColor): alternativa.
SPIF_SENDWININICHANGE notifica el cambio a todas las ventanas.
Ejemplos de ejecución TEST:
ChangeDesktopColor.exe 0→0.jpgChangeDesktopColor.exe 999→4.jpg(predeterminado)ChangeDesktopColor.exe 1 2→0.jpg(primer argumento)
Usos prácticos
Ideal para rotar fondos: imagen → negro → imagen → ...
Usa fondos como "chuleta": 0.jpg muestra combinaciones clave para Razer NAGA X (12+12 botones con modificador). Acceso rápido a macros sin perder foco.
Lecciones clave:
- Ocultación por enlazador supera la programática — sin parpadeo.
_TESTsimplifica desarrollo con archivos0.jpg-4.jpglocales.- Verificación con
wcsstrdistingue archivo de color sólido. SPIF_UPDATEINIFILEguarda en registro.- Argumento en línea de comandos selecciona fondo (0-4).
— Editorial Team
Aún no hay comentarios.