WRL を使用して組み込みの winrt コンポーネントを返すにはどうすればよいですか?

StackOverflow https://stackoverflow.com//questions/12687502

  •  12-12-2019
  •  | 
  •  

質問

WRL を使用して winrt コンポーネントを作成する場合、問題は、 ABI::Windows::xxx 名前空間があり、使用できません Windows::UI::Xaml::Media::Imaging WRL の名前空間。

では、戻り値として組み込みの winrt コンポーネントを作成するにはどうすればよいでしょうか?

// idl
import "inspectable.idl";
import "Windows.Foundation.idl";
import "Windows.UI.Xaml.Media.Imaging.idl";

namespace Decoder
{
    interface IPhotoDecoder;
    runtimeclass PhotoDecoder;

    interface IPhotoDecoder : IInspectable
    {
        HRESULT Decode([in] int width, [in] int height, [out, retval] Windows.UI.Xaml.Media.Imaging.BitmapImage **ppBitmapImage);
    }

    [version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)]
    runtimeclass PhotoDecoder
    {
         [default] interface IPhotoDecoder;
    }
}

// cpp
using namespace Microsoft::WRL;
using namespace Windows::Foundation;
using namespace ABI::Windows::UI::Xaml::Media::Imaging;
namespace ABI
{
    namespace Decoder
    {
        class PhotoDecoder: public RuntimeClass<IPhotoDecoder>
        {
            InspectableClass(L"Decoder.PhotoDecoder", BaseTrust)

            public:
            PhotoDecoder()
            {
            }

            HRESULT __stdcall Decode(_In_ int width, _In_ int height, _Out_ IBitmapImage **ppBitmapImage)
            {
                // How to create Windows.UI.Xaml.Media.Imaging.BitmapImage without using Windows::UI::Xaml::Media::Imaging
            }

        };

        ActivatableClass(PhotoDecoder);
    }
}
役に立ちましたか?

解決

名前空間には 2 つのセットがあります。

  • グローバル名前空間に根ざしたもの (例: Windows::Foundation)
  • に根ざしたもの ABI 名前空間 (例: ABI::Windows::Foundation)

それぞれの内容は「同じ」です。例えば、 Windows::Foundation::IUriRuntimeClass と同じインターフェースに名前を付けます ABI::Windows::Foundation::IUriRuntimeClass.

では、なぜ 2 セットの名前空間があるのでしょうか?グローバル名前空間をルートとする名前空間は、C++/CX で使用するために予約されています。これらの名前空間でランタイム クラスのプロジェクションを生成します。WRL を使用するときは、常に、 ABI 名前空間 (「投影されていない」名前、つまり、まさに ABI レイヤーに存在するものです)。

ランタイム クラスは、2 つの方法のいずれかでインスタンス化 (「アクティブ化」) されます。型がデフォルトで構築可能な場合、呼び出しによってデフォルトで構築される可能性があります。 RoActivateInstance. 。型が他のコンストラクターを宣言している場合、それらのコンストラクターは、呼び出してランタイム型のアクティベーション ファクトリを取得することによって呼び出すことができます。 RoGetActivationFactory. 。例として、デフォルトで次のように構築できます。 BitmapImage そのようです:

using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

using namespace ABI::Windows::UI::Xaml::Media::Imaging;

HStringReference classId(RuntimeClass_Windows_UI_Xaml_Media_Imaging_BitmapImage);

ComPtr<IInspectable> inspectable;
if (FAILED(RoActivateInstance(classId.Get(), inspectable.GetAddressOf())))
{
    // Handle failure
}

ComPtr<IBitmapImage> bitmapImage;
if (FAILED(inspectable.As(&bitmapImage)))
{
    // Handle failure
}

WRL には便利な関数テンプレートもあります。 Windows::Foundation::ActivateInstance, 、両方とも呼び出します RoActivateInstance そして実行します QueryInterface 目的のターゲット インターフェイスに移動します。

using namespace Windows::Foundation;

ComPtr<IBitmapImage> bitmapImage;
if (FAILED(ActivateInstance(classId.Get(), bitmapImage.GetAddressOf())))
{
    // Handle failure
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top