Windowsイメージングコンポーネント(WIC、Windows Imaging Component)(Microsoft Docs)のWICコンポーネントの情報を取得するサンプルコードです。基本的な流れは「IWICImagingFactoryの作成→CreateComponentEnumeratorでIEnumUnknownを作成→IEnumUnknownで取得したIUnknownをIWICComponentInfoに変換→IWICComponentInfoから情報を取得」です。
すべてのWICコンポーネントの情報を取得する
#include <format>
#include <string>
#include <iostream>
#define STRICT
#define NOMINMAX
#include <Windows.h>
#include <wincodec.h>
#pragma comment(lib, "WindowsCodecs.lib")
constexpr const wchar_t* strptr_notnull(std::wstring_view s) noexcept
{
return s.empty() ? L"" : s.data();
}
std::wstring GUIDToWString(REFGUID guid)
{
std::wstring s(38, L'\0');
if (StringFromGUID2(guid, s.data(), 39) == 0)
return {};
return std::move(s);
}
std::wstring GetFriendlyName(IWICComponentInfo* info)
{
UINT actualLen;
if (SUCCEEDED(info->GetFriendlyName(0, nullptr, &actualLen)))
{
if (actualLen == 0) return L"";
std::wstring s(actualLen - 1, L'\0');
if (SUCCEEDED(info->GetFriendlyName(actualLen, s.data(), &actualLen)))
{
return std::move(s);
}
}
return {};
}
std::wstring GetAuthor(IWICComponentInfo* info)
{
UINT actualLen;
if (SUCCEEDED(info->GetAuthor(0, nullptr, &actualLen)))
{
if (actualLen == 0) return L"";
std::wstring s(actualLen - 1, L'\0');
if (SUCCEEDED(info->GetAuthor(actualLen, s.data(), &actualLen)))
{
return std::move(s);
}
}
return {};
}
std::wstring GetSpecVersion(IWICComponentInfo* info)
{
UINT actualLen;
if (SUCCEEDED(info->GetSpecVersion(0, nullptr, &actualLen)))
{
if (actualLen == 0) return L"";
std::wstring s(actualLen - 1, L'\0');
if (SUCCEEDED(info->GetSpecVersion(actualLen, s.data(), &actualLen)))
{
return std::move(s);
}
}
return {};
}
std::wstring GetVersion(IWICComponentInfo* info)
{
UINT actualLen;
if (SUCCEEDED(info->GetVersion(0, nullptr, &actualLen)))
{
if (actualLen == 0) return L"";
std::wstring s(actualLen - 1, L'\0');
if (SUCCEEDED(info->GetVersion(actualLen, s.data(), &actualLen)))
{
return std::move(s);
}
}
return {};
}
std::wstring_view ToWStringView(
WICComponentType value,
std::wstring_view defaultString = {})
{
switch (value) {
case WICDecoder: return L"WICDecoder";
case WICEncoder: return L"WICEncoder";
case WICPixelFormatConverter: return L"WICPixelFormatConverter";
case WICMetadataReader: return L"WICMetadataReader";
case WICMetadataWriter: return L"WICMetadataWriter";
case WICPixelFormat: return L"WICPixelFormat";
case WICAllComponents: return L"WICAllComponents";
default: return defaultString;
}
}
std::wstring_view ToWStringView(
WICComponentSigning value,
std::wstring_view defaultString = {})
{
switch (value) {
case WICComponentSigned: return L"WICComponentSigned";
case WICComponentUnsigned: return L"WICComponentUnsigned";
case WICComponentSafe: return L"WICComponentSafe";
case WICComponentDisabled: return L"WICComponentDisabled";
default: return defaultString;
}
}
int wmain()
{
std::wcout.imbue(std::locale("", std::locale::ctype));
if (FAILED(::CoInitializeEx(nullptr, COINIT::COINIT_APARTMENTTHREADED)))
return -1;
IWICImagingFactory* pWicImagingFactory;
if (SUCCEEDED(::CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pWicImagingFactory))))
{
IEnumUnknown* pEnumUnknown;
if (SUCCEEDED(pWicImagingFactory->CreateComponentEnumerator(
WICComponentType::WICAllComponents,
WICComponentEnumerateOptions::WICComponentEnumerateDefault,
&pEnumUnknown)))
{
std::wcout << L"FriendlyName, Author, Version, SpecVersion, CLSID, VendorGUID, SigningStatus" << std::endl;
IUnknown* punkWicComponentInfo;
while (pEnumUnknown->Next(1, &punkWicComponentInfo, nullptr) == S_OK)
{
IWICComponentInfo* pWicComponentInfo;
if (SUCCEEDED(punkWicComponentInfo->QueryInterface(IID_PPV_ARGS(&pWicComponentInfo))))
{
auto friendlyName{ GetFriendlyName(pWicComponentInfo) };
auto author{ GetAuthor(pWicComponentInfo) };
auto version{ GetVersion(pWicComponentInfo) };
auto specVersion{ GetSpecVersion(pWicComponentInfo) };
std::wstring clsidStr;
std::wstring vendorGuidStr;
std::wstring componentTypeStr;
std::wstring signingStatusStr;
if (CLSID clsid; SUCCEEDED(pWicComponentInfo->GetCLSID(&clsid)))
clsidStr = GUIDToWString(clsid);
if (CLSID clsid; SUCCEEDED(pWicComponentInfo->GetVendorGUID(&clsid)))
vendorGuidStr = GUIDToWString(clsid);
if (WICComponentType type; SUCCEEDED(pWicComponentInfo->GetComponentType(&type)))
vendorGuidStr = ToWStringView(type);
if (DWORD status; SUCCEEDED(pWicComponentInfo->GetSigningStatus(&status)))
signingStatusStr = ToWStringView(static_cast<WICComponentSigning>(status));
std::wcout
<< std::format(L"{}, {}, {}, {}, {}, {}, {}",
strptr_notnull(friendlyName),
strptr_notnull(author),
strptr_notnull(version),
strptr_notnull(specVersion),
strptr_notnull(clsidStr),
strptr_notnull(vendorGuidStr),
strptr_notnull(signingStatusStr))
<< std::endl;
}
}
pEnumUnknown->Release();
}
pWicImagingFactory->Release();
}
::CoUninitialize();
return 0;
}
デコーダーの対応拡張子を取得する
#include <format>
#include <string>
#include <iostream>
#define STRICT
#define NOMINMAX
#include <Windows.h>
#include <wincodec.h>
#pragma comment(lib, "WindowsCodecs.lib")
constexpr const wchar_t* strptr_notnull(std::wstring_view s) noexcept
{
return s.empty() ? L"" : s.data();
}
std::wstring GetFriendlyName(IWICComponentInfo* info)
{
UINT actualLen;
if (SUCCEEDED(info->GetFriendlyName(0, nullptr, &actualLen)))
{
if (actualLen == 0) return L"";
std::wstring s(actualLen - 1, L'\0');
if (SUCCEEDED(info->GetFriendlyName(actualLen, s.data(), &actualLen)))
{
return std::move(s);
}
}
return {};
}
std::wstring GetFileExtensions(IWICBitmapDecoderInfo* info)
{
UINT actualLen;
if (SUCCEEDED(info->GetFileExtensions(0, nullptr, &actualLen)))
{
if (actualLen == 0) return L"";
std::wstring s(actualLen - 1, L'\0');
if (SUCCEEDED(info->GetFileExtensions(actualLen, s.data(), &actualLen)))
{
return std::move(s);
}
}
return {};
}
std::wstring GetAuthor(IWICComponentInfo* info)
{
UINT actualLen;
if (SUCCEEDED(info->GetAuthor(0, nullptr, &actualLen)))
{
if (actualLen == 0) return L"";
std::wstring s(actualLen - 1, L'\0');
if (SUCCEEDED(info->GetAuthor(actualLen, s.data(), &actualLen)))
{
return std::move(s);
}
}
return {};
}
int wmain()
{
std::wcout.imbue(std::locale("", std::locale::ctype));
if (FAILED(::CoInitializeEx(nullptr, COINIT::COINIT_APARTMENTTHREADED)))
return -1;
IWICImagingFactory* pWicImagingFactory;
if (SUCCEEDED(::CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pWicImagingFactory))))
{
IEnumUnknown* pEnumUnknown;
if (SUCCEEDED(pWicImagingFactory->CreateComponentEnumerator(
WICComponentType::WICDecoder,
WICComponentEnumerateOptions::WICComponentEnumerateDefault,
&pEnumUnknown)))
{
std::wcout << L"FriendlyName, Author, FileExts" << std::endl;
IUnknown* punkWicComponentInfo;
while (pEnumUnknown->Next(1, &punkWicComponentInfo, nullptr) == S_OK)
{
https:
IWICBitmapDecoderInfo* pWicDecoderInfo;
if (SUCCEEDED(punkWicComponentInfo->QueryInterface(IID_PPV_ARGS(&pWicDecoderInfo))))
{
auto friendlyName{ GetFriendlyName(pWicDecoderInfo) };
auto author{ GetAuthor(pWicDecoderInfo) };
auto fileExts{GetFileExtensions(pWicDecoderInfo)};
std::wcout
<< std::format(L"{}, {}, \"{}\"",
strptr_notnull(friendlyName),
strptr_notnull(author),
strptr_notnull(fileExts))
<< std::endl;
}
}
pEnumUnknown->Release();
}
pWicImagingFactory->Release();
}
::CoUninitialize();
return 0;
}