2016-10-31 25 views
0

私は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; 
} 
+4

定義は機能しません。コンパイルされませんか?あなたは何を期待していませんか?ビールを飲んだり、トークショーを見たりして、一日中ソファに横たわっていますか? – user4581301

+0

使用しているVisual Studioのバージョンは何ですか?代わりに 'CLSID_WICImagingFactory1'か' CLSID_WICImagingFactory2'を試してください。初期化の残りの部分も表示してください。 –

+3

コンパイラエラーまたはランタイムエラーが発生していますか?後者の場合、 'CoCreateInstance()'は実際にどのような 'HRESULT'値を返しますか?それが失敗する理由を教えてくれるでしょう。 –

答えて

2

あなたがこれを打つことができた2つの主な理由はありますが仕事関数のCoCreateInstance(...)です。

(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のデスクトップアプリの

、あなたはおそらく、そうでない場合は、それをサポートするプラットフォームやWIC1にWIC2を初期化し、次の使用したい - DirectXTexDirectXTKWICTextureLoaderで見つけたコードを。

#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; 
} 

これは、スレッドセーフです確実にするためにInitOnceExecuteOnceを使用しています。これにより、どのスレッドがGetWICを最初に呼び出しても、WICファクトリが正確に1回作成されます。私はC++ 11ラムダa.k.a. 匿名関数コールバックを使用しています。 WICファクトリへの実際のポインタは、INIT_ONCE構造体の内部に格納されます。 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ヘッダーはWICおよびWICバージョン2をサポートしますが、WICバージョン2定義は通常定義されていませんWindows 7またはそれ以降のビルド用。したがって、_WIN32_WINNT0x0601(Windows 7)または0x0600(Windows Vista)に設定されている場合でも、_WIN32_WINNTがWIC2タイプを定義するために、wincodec.hヘッダーを取得するために、ビルド設定で_WIN7_PLATFORM_UPDATEプリプロセッサシンボルを使用します。この場合、WIC2サポートが実際にオペレーティングシステムにインストールされておらず、元のWICファクトリを使用するためにフォールバックするケースを処理する必要があります。

  • それ以外の場合、既定値はWICバージョン1になる既定のWICファクトリになります。このコードパスは、WIC2タイプが最初のものであるWindows 8.0 SDKより古いWindows SDKで構築されます。wincodec.h

あなたは工場が実際にWIC2の工場だったかどうかを知る必要があるいくつかの場所があるので、あなたがGUID_WICPixelFormat96bppRGBFloatGUID_WICPixelFormat32bppRGBGUID_WICPixelFormat64bppRGB、またはGUID_WICPixelFormat64bppPRGBAHalfを使用しようとしている場合、私は特に、IsWIC2機能を持っていますピクセル形式。 WIC2を使用していない場合は、代わりに他の形式を使用する必要があります。

WICとWIC2の相違点の詳細については、MSDNthis blog postを参照してください。

+0

ありがとうございます。しかし、このコードは本当に読めないように見えるし、私はあなたがそこで何をしたのかは分かりません:D –

+0

十分に公正です。私はより多くの説明と参考資料で答えを更新しました。このコードスニペットは、マイクロソフトのたくさんの人からの長年にわたるコードレビューを表しているので、実際には「最良のもの」を目指しています。 –