返回首页

C++ Windows 壁纸更改:WinAPI 和 COM

C++ 程序循环更改 Windows 桌面壁纸和纯色。描述使用链接器隐藏控制台、TEST/Release 配置、通过 SystemParametersInfo 检查当前背景并通过 WinAPI/COM 设置。

在 Windows 上使用 C++ 编程方式更改壁纸和颜色
Advertisement 728x90

Windows C++ 程序化切换桌面壁纸与颜色

这个 Windows C++ 程序可在图片与纯色之间切换桌面壁纸。它运行时无可见控制台窗口。调试模式下窗口显示用于排查问题;发布版和测试版则隐藏窗口。

隐藏控制台的两种方法:

  • 程序化隐藏 使用 GetConsoleWindow()ShowWindow(hWnd, SW_HIDE)。窗口隐藏前会短暂闪烁。
  • 链接器指令(推荐方式):
#ifndef _DEBUG
#pragma comment(linker, "/subsystem:windows")
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
#endif

第一条指令将其构建为 GUI 应用,使用 WinMain() 入口。第二条保留 main() 但跳过控制台创建。无闪烁。

Google AdInline article slot

构建配置

三个 Visual Studio 配置:DebugReleaseTEST(继承自 Release)。

TEST 在项目属性(C/C++ → 预处理器)中添加 _TEST 预处理器定义。

  • TEST:exe 文件夹中放置图片 0.jpg...4.jpg。运行:ChangeDesktopColor.exe X(X=0-4)。
  • Release:使用完整文件路径,与 exe 位置无关。

TEST 调试时,在 Debug 配置下取消注释 #define _TEST

Google AdInline article slot

获取 exe 路径(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] 为空,因此使用 GetModuleFileName

根据参数选择文件:

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

检查当前壁纸

获取当前壁纸:

wchar_t wallFile[MAX_PATH] = { L'\0' };
SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, wallFile, 0);
wchar_t* ptr = wcsstr(wallFile, fileName.c_str());
  • ptr == NULL:纯色或不同文件。
  • wallFile 保存文件名,纯色时为空。

设置壁纸或颜色

切换逻辑:

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
}

通过 #define MyCOM 选择 API:

  • WinAPI (SetDesktopSolidColor):首选方法。
  • COM (ChangeDesktopBackgroundColor):备选。

SPIF_SENDWININICHANGE 向所有窗口广播更新。

TEST 运行示例:

  • ChangeDesktopColor.exe 00.jpg
  • ChangeDesktopColor.exe 9994.jpg(默认)
  • ChangeDesktopColor.exe 1 20.jpg(首参数)

实际应用

适合循环切换壁纸:图片 → 黑色 → 图片 → ...

将壁纸用作备忘:0.jpg 显示 Razer NAGA X(12+12 键+修饰键)的快捷键组合。快速访问宏而不丢失焦点。

关键要点:

  • 链接器隐藏优于程序化——无闪烁。
  • _TEST 用本地 0.jpg-4.jpg 文件简化开发。
  • wcsstr 检查区分文件与纯色。
  • SPIF_UPDATEINIFILE 保存至注册表。
  • 命令行参数选择壁纸(0-4)。

— Editorial Team

Advertisement 728x90

继续阅读