IWICImagingFactory 的 CoCreateInstance
Posted
技术标签:
【中文标题】IWICImagingFactory 的 CoCreateInstance【英文标题】:CoCreateInstance of IWICImagingFactory 【发布时间】:2013-02-10 15:15:45 【问题描述】:我在我的 Windows 7 机器上运行 Visual Studio 2012。
当我运行这里找到的 SimpleDirect2dApplication 时:http://technet.microsoft.com/en-us/subscriptions/dd940321%28v=vs.85%29.aspx
hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&m_pWICFactory)
);
CoCreateInstance 因“未注册类”而失败,工厂的 ptr 为 0。
任何帮助将不胜感激。
【问题讨论】:
所以在提出问题后,我立即在这里找到了答案social.msdn.microsoft.com/Forums/en-US/windowswic/thread/…CLSID_WICImagingFactory 需要更改为 CLSID_WICImagingFactory1 才能使其适用于 windows7。 其实看SDK版本。较旧的 SDK 有CLSID_WICImagingFactory
指向正确的 CLSID,并且代码可以正常工作。 Windows SDK 上的意外、不明显且可能不准确的更改。
这是在 wincodec.idl 中正确定义的,它们具有完全相同的 guid。也许这在 8 SDK 的测试版中被破坏了,现在不是。
【参考方案1】:
根据 Microsoft 论坛中的 answer,Windows SDK 8.0 的一项重大更改要求您将 _WIN32_WINNT
定义为 0x0600
以向后兼容 Windows Vista 或定义为 0x0601
以向后兼容 Windows 7。
【讨论】:
【参考方案2】:以下是我用来为 WIC 和 WIC2 场景创建 WIC 的代码:
namespace
bool g_WIC2 = false;
BOOL WINAPI InitializeWICFactory(PINIT_ONCE, PVOID, PVOID *ifactory) noexcept
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory2,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory2),
ifactory
);
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),
ifactory
);
return SUCCEEDED(hr) ? TRUE : FALSE;
#else
return SUCCEEDED(CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
ifactory)) ? TRUE : FALSE;
#endif
bool IsWIC2() noexcept
return g_WIC2;
IWICImagingFactory* GetWIC() noexcept
static INIT_ONCE s_initOnce = INIT_ONCE_STATIC_INIT;
IWICImagingFactory* factory = nullptr;
if (!InitOnceExecuteOnce(
&s_initOnce,
InitializeWICFactory,
nullptr,
reinterpret_cast<LPVOID*>(&factory)))
return nullptr;
return factory;
这处理从任何线程创建一次工厂。您只需调用即可使用它:
auto pWIC = GetWIC();
if (!pWIC)
// error
对于您关心 WIC 与 WIC2 的少数情况,您可以使用 IsWIC2
:
if (targetFormat && memcmp(&guidContainerFormat, &GUID_ContainerFormatBmp, sizeof(WICPixelFormatGUID)) == 0 && IsWIC2())
// Opt-in to the WIC2 support for writing 32-bit Windows BMP files with an alpha channel
PROPBAG2 option = ;
option.pstrName = const_cast<wchar_t*>(L"EnableV5Header32bppBGRA");
VARIANT varValue;
varValue.vt = VT_BOOL;
varValue.boolVal = VARIANT_TRUE;
(void)props->Write(1, &option, &varValue);
我过去曾为此代码使用 C++11 lambda,但 clang/LLVM 不太喜欢它。
【讨论】:
【参考方案3】:使用这个
#if defined(CLSID_WICImagingFactory)
#undef CLSID_WICImagingFactory
#endif
然后你就可以通过了
参考: http://skia.googlecode.com/svn/trunk/src/ports/SkImageDecoder_WIC.cpp
【讨论】:
此答案中的链接已损坏。 很难理解这个答案中提出的解决方案(#undef
-存在CLSID_WICImagingFactory
宏)应该如何工作。能详细点吗?
链接现在在这里:github.com/Igalia/skia/blob/master/src/ports/…以上是关于IWICImagingFactory 的 CoCreateInstance的主要内容,如果未能解决你的问题,请参考以下文章