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 桌面应用程序,您可以使用 CoInitialize
或 CoInitializeEx
来执行此操作。对于 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 DirectXTK 的 WICTextureLoader
中找到的代码。
#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_WICPixelFormat96bppRGBFloat
, GUID_WICPixelFormat32bppRGB
、GUID_WICPixelFormat64bppRGB
或 GUID_WICPixelFormat64bppPRGBAHalf
像素格式。如果您不使用 WIC2,则需要改用其他格式。
有关 WIC 与 WIC2 的不同之处的详细信息,请参阅 MSDN as well as this blog post。
我尝试用 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 桌面应用程序,您可以使用 CoInitialize
或 CoInitializeEx
来执行此操作。对于 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 DirectXTK 的 WICTextureLoader
中找到的代码。
#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 callsGetWIC
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 theINIT_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_WICPixelFormat96bppRGBFloat
, GUID_WICPixelFormat32bppRGB
、GUID_WICPixelFormat64bppRGB
或 GUID_WICPixelFormat64bppPRGBAHalf
像素格式。如果您不使用 WIC2,则需要改用其他格式。
有关 WIC 与 WIC2 的不同之处的详细信息,请参阅 MSDN as well as this blog post。