如何使用WRL返回一个内置的WinRT的成分?(How to return a build-in w

2019-09-23 08:20发布

当我创建使用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);
    }
}

Answer 1:

有两套命名空间:

  • 那些植根于全局命名空间(如Windows::Foundation
  • 那些植根于ABI命名空间(如ABI::Windows::Foundation

每个的内容是“一样。” 例如, Windows::Foundation::IUriRuntimeClass名称相同的接口ABI::Windows::Foundation::IUriRuntimeClass

那么,为什么有两套命名空间? 植根于全局命名空间中的名称空间被保留用于通过C ++ / CX使用:它产生这些命名空间中其运行时类的投影。 当你使用WRL,你永远植根在命名空间的工作ABI命名空间(这是“未投影”的名字,也就是说,他们在ABI层正是存在)。

运行时类实例化(“激活”)两种方式中的一种。 如果类型是缺省构造,也可以默认调用构造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
}


文章来源: How to return a build-in winrt component using WRL?