You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MinGW环境下用C++调用Win32的IDesktopWallpaper接口?

如何正确使用IDesktopWallpaper接口的方法?

问题背景

我想使用IDesktopWallpaper::SetWallpaper()或IDesktopWallpaper::GetMonitorDevicePathCount()等方法,但误以为IDesktopWallpaper是命名空间,编写了如下代码:

#include <windows.h>
#include <shlobj.h>

#include <ostream>
#include <iostream>

int main(int argc, char *argv[])
{
    UINT count;
    IDesktopWallpaper::GetMonitorDevicePathCount(&count);
    std::cout << count << std::endl;

    return 0;
}

执行编译命令:

g++   -c -o obj/Wallpaper.o src/Wallpaper.cpp

出现错误:

src/Wallpaper.cpp: In function 'int main(int, char**)':
src/Wallpaper.cpp:32:49: error: cannot call member function 'virtual HRESULT IDesktopWallpaper::GetMonitorDevicePathCount(UINT*)' without object
32 | IDesktopWallpaper::GetMonitorDevicePathCount(&count);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~

不清楚如何创建IDesktopWallpaper对象,也不知道该实例化哪个类,请问该如何使用这些方法?

解决方案

IDesktopWallpaper是Windows COM接口,不能直接通过类名调用成员方法,必须先创建接口的实例,步骤如下:

  1. 初始化COM库:在使用任何COM接口前,需要调用CoInitializeEx初始化COM环境。
  2. 创建接口实例:通过CoCreateInstance函数创建IDesktopWallpaper的实例,指定CLSID为CLSID_DesktopWallpaper,IID为IID_IDesktopWallpaper。
  3. 调用接口方法:通过创建好的实例调用GetMonitorDevicePathCount等方法。
  4. 释放资源:使用完接口后调用Release释放实例,最后调用CoUninitialize关闭COM库。

修正后的完整代码:

#include <windows.h>
#include <shlobj.h>
#include <iostream>

int main(int argc, char *argv[])
{
    // 初始化COM库
    HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
    if (FAILED(hr)) {
        std::cerr << "COM初始化失败,错误码: " << hr << std::endl;
        return 1;
    }

    IDesktopWallpaper* pWallpaper = nullptr;
    // 创建IDesktopWallpaper实例
    hr = CoCreateInstance(CLSID_DesktopWallpaper, nullptr, CLSCTX_ALL, IID_IDesktopWallpaper, reinterpret_cast<void**>(&pWallpaper));
    if (FAILED(hr)) {
        std::cerr << "创建IDesktopWallpaper实例失败,错误码: " << hr << std::endl;
        CoUninitialize();
        return 1;
    }

    UINT count = 0;
    // 调用接口方法
    hr = pWallpaper->GetMonitorDevicePathCount(&count);
    if (SUCCEEDED(hr)) {
        std::cout << "显示器数量: " << count << std::endl;
    } else {
        std::cerr << "获取显示器数量失败,错误码: " << hr << std::endl;
    }

    // 释放接口实例
    pWallpaper->Release();
    // 关闭COM库
    CoUninitialize();

    return 0;
}

关键说明

  • COINIT_APARTMENTTHREADED是线程模型,IDesktopWallpaper要求使用单线程单元(STA)模型。
  • CLSID_DesktopWallpaper是实现IDesktopWallpaper接口的类的CLSID,IID_IDesktopWallpaper是接口的IID,这两个宏定义在shlobj.h中。
  • 所有COM操作都需要检查HRESULT返回值,确保操作成功。

内容的提问来源于stack exchange,提问作者jdarthenay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:14:55