CoCreateInstance 不工作

CoCreateInstance dont work

我尝试用 direct2d 制作位图。 问题是函数 CoCreateInstance(...) 它不会工作

 HRESULT Renderer::InitImagingFactory()
{
    if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) return E_FAIL;


    if (FAILED(CoCreateInstance(
        CLSID_WICImagingFactory,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_IWICImagingFactory,
        reinterpret_cast<void **>(&m_imagingfactory)))) return E_FAIL;

    return S_OK;
}

您可能会遇到这个问题的主要原因有两个。

(1)调用此函数前需要初始化COM。对于经典的 Win32 桌面应用程序,您可以使用 CoInitializeCoInitializeEx 来执行此操作。对于 Windows 运行时平台,您将使用 Windows::Foundation::Initialize.

HRESULT hr = CoInitializeEx(nullptr, COINITBASE_MULTITHREADED);
if (FAILED(hr))
    // error

(2) 您需要确保为您的目标平台正确设置了 _WIN32_WINNT——参见 Using the Windows Headers

对于经典的 Win32 桌面应用程序,您可能希望使用以下代码在支持它的平台上初始化 WIC2 或在其他平台上初始化 WIC1——在 DirectXTex and DirectXTKWICTextureLoader 中找到的代码。

#include <wincodec.h>

namespace
{
    bool g_WIC2 = false;
}

bool IsWIC2()
{
    return g_WIC2;
}

IWICImagingFactory* GetWIC()
{
    static INIT_ONCE s_initOnce = INIT_ONCE_STATIC_INIT;

    IWICImagingFactory* factory = nullptr;
    InitOnceExecuteOnce(&s_initOnce,
        [](PINIT_ONCE, PVOID, PVOID *factory) -> BOOL
        {
        #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
            HRESULT hr = CoCreateInstance(
                CLSID_WICImagingFactory2,
                nullptr,
                CLSCTX_INPROC_SERVER,
                __uuidof(IWICImagingFactory2),
                factory
                );

            if ( SUCCEEDED(hr) )
            {
                // WIC2 is available on Windows 10, Windows 8.x, and Windows 7 SP1 with KB 2670838 installed
                g_WIC2 = true;
                return TRUE;
            }
            else
            {
                hr = CoCreateInstance(
                    CLSID_WICImagingFactory1,
                    nullptr,
                    CLSCTX_INPROC_SERVER,
                    __uuidof(IWICImagingFactory),
                    factory
                    );
                return SUCCEEDED(hr) ? TRUE : FALSE;
            }
        #else
            return SUCCEEDED( CoCreateInstance(
                CLSID_WICImagingFactory,
                nullptr,
                CLSCTX_INPROC_SERVER,
                __uuidof(IWICImagingFactory),
                factory) ) ? TRUE : FALSE;
        #endif
        }, nullptr, reinterpret_cast<LPVOID*>(&factory));

    return factory;
}

This uses InitOnceExecuteOnce to ensure it's thread-safe. This ensures that the WIC factory is created exactly once no matter which thread calls GetWIC first. I'm using a C++11 lambda a.k.a. an anonymous function for the callback. The actual pointer to the WIC factory is stored inside the INIT_ONCE structure. See Using One-Time Initialization

此代码旨在涵盖所有可能的平台设置。

  • 为 Windows 商店、通用 Windows 平台 (UWP) 应用程序或 Xbox 构建时,_WIN32_WINNT 变量将为 Windows 8或更高版本。这也适用于仅支持 Windows 8.0 或更高版本的经典 Win32 桌面应用程序。

  • 在为 Windows 7 构建时 _WIN32_WINNT 将设置为低于 Windows 8 的值。Windows 8.x SDK 和Windows 10 SDK WIC header 同时支持 WIC 和 WIC 版本 2,但 WIC 版本 2 定义通常不为 Windows 7 或更低版本定义。因此,您还可以在构建设置中使用 _WIN7_PLATFORM_UPDATE 预处理器符号来获取 wincodec.h header 来定义 WIC2 类型,即使 _WIN32_WINNT 设置为 0x0601 (Windows 7) 或 0x0600 (Windows Vista)。在这种情况下,您需要处理操作系统上实际未安装 WIC2 支持的情况,并回退以使用原始 WIC 工厂。

  • 否则,它只是默认为默认 WIC 工厂,这将是 WIC 版本 1。此代码路径也将使用比 Windows 8.0 更旧的 Windows SDK 构建wincodec.h.

  • 中第一个WIC2类型的SDK

我有 IsWIC2 函数,因为有几个地方你需要知道工厂是否真的是 WIC2 工厂,特别是如果你试图使用 GUID_WICPixelFormat96bppRGBFloatGUID_WICPixelFormat32bppRGBGUID_WICPixelFormat64bppRGBGUID_WICPixelFormat64bppPRGBAHalf 像素格式。如果您不使用 WIC2,则需要改用其他格式。

有关 WIC 与 WIC2 的不同之处的详细信息,请参阅 MSDN as well as this blog post