如何使用WRL返回内置的winrt组件? [英] How to return a build-in winrt component using WRL?

查看:286
本文介绍了如何使用WRL返回内置的winrt组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用WRL创建winrt组件时,问题是我只能使用 ABI :: Windows :: xxx 命名空间,我不能使用 WRL中的Windows :: UI :: Xaml :: Media :: Imaging 命名空间。



然后,如何创建内置的winrt组件作为返回值?

  // idl 
importinspectable.idl;
importWindows.Foundation.idl;
importWindows.UI.Xaml.Media.Imaging.idl;

命名空间解码器
{
接口IPhotoDecoder;
runtimeclass PhotoDecoder;

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

[version(COMPONENT_VERSION),可激活(COMPONENT_VERSION)]
runtimeclass PhotoDecoder
{
[默认] interface IPhotoDecoder;
}
}

// cpp
使用命名空间Microsoft :: WRL;
使用命名空间Windows :: Foundation;
使用命名空间ABI :: Windows :: UI :: Xaml :: Media :: Imaging;
命名空间ABI
{
命名空间解码器
{
class PhotoDecoder:public RuntimeClass< IPhotoDecoder>
{
InspectableClass(LDecoder.PhotoDecoder,BaseTrust)

public:
PhotoDecoder()
{
} $ b b
HRESULT __stdcall解码(_In_ int width,_In_ int height,_Out_ IBitmapImage ** ppBitmapImage)
{
//如何创建Windows.UI.Xaml.Media.Imaging.BitmapImage而不使用Windows :: UI :: Xaml :: Media :: Imaging
}

};

ActivatableClass(PhotoDecoder);
}
}


解决方案

是两组命名空间:


  • 这些根植于全局命名空间(例如 Windows :: Foundation ABI :: Windows :: Foundation ) / code>)



每个文件的内容都是相同的。例如, Windows :: Foundation :: IUriRuntimeClass 命名与相同的接口ABI :: Windows :: Foundation :: IUriRuntimeClass



那么,为什么有两组命名空间?全局命名空间中的命名空间保留供C ++ / CX使用:它生成其在这些命名空间中的运行时类的投影。当您使用WRL时,您将始终使用以 ABI 命名空间为根的命名空间(它们是未预测的名称,也就是说,它们是存在于ABI层)。



运行时类以两种方式之一被实例化(激活)。如果类型是默认可构造的,则可以通过调用 RoActivateInstance 。如果类型声明了其他构造函数,那么可以通过调用 RoGetActivationFactory 。例如,你可以默认构造一个 BitmapImage

 使用命名空间Microsoft :: WRL; 
使用命名空间Microsoft :: WRL :: Wrappers;

使用命名空间ABI :: Windows :: UI :: Xaml :: Media :: Imaging;

HStringReference classId(RuntimeClass_Windows_UI_Xaml_Media_Imaging_BitmapImage);

ComPtr< IInspectable>可检查;
if(FAILED(RoActivateInstance(classId.Get(),inspectable.GetAddressOf())))
{
//处理失败
}

ComPtr< IBitmapImage> bitmapImage;
if(FAILED(inspectable.As(& bitmapImage)))
{
//处理失败
}

WRL还有一个有用的函数模板, Windows :: Foundation :: ActivateInstance ,它们都调用 RoActivateInstance code> QueryInterface 到所需的目标接口:

  

ComPtr< IBitmapImage> bitmapImage;
if(FAILED(ActivateInstance(classId.Get(),bitmapImage.GetAddressOf())))
{
//处理失败
}


When I create a winrt component using WRL, the problem is that I can only use ABI::Windows::xxx namespace, and I cannot use Windows::UI::Xaml::Media::Imaging namespace in WRL.

Then, how to create a build-in winrt component as a return value?

// 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);
    }
}

解决方案

There are two sets of namespaces:

  • those rooted in the global namespace (e.g. Windows::Foundation)
  • those rooted in the ABI namespace (e.g. ABI::Windows::Foundation)

The contents of each are "the same." For example, Windows::Foundation::IUriRuntimeClass names the same interface as ABI::Windows::Foundation::IUriRuntimeClass.

So, why are there two sets of namespaces? the namespaces rooted in the global namespace are reserved for use by C++/CX: it generates its projections of runtime classes in those namespaces. When you're using WRL, you'll always work with the namespaces rooted in the ABI namespace (which are the "unprojected" names, that is, they're exactly what exist at the ABI layer).

Runtime classes are instantiated ("activated") in one of two ways. If the type is default constructible, it may be default constructed by calling RoActivateInstance. If a type declares other constructors, those constructors may be called by getting the activation factory for the runtime type by calling RoGetActivationFactory. As an example, you can default construct a BitmapImage like so:

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 also has a useful function template, Windows::Foundation::ActivateInstance, that both calls RoActivateInstance and performs the QueryInterface to the desired target interface:

using namespace Windows::Foundation;

ComPtr<IBitmapImage> bitmapImage;
if (FAILED(ActivateInstance(classId.Get(), bitmapImage.GetAddressOf())))
{
    // Handle failure
}

这篇关于如何使用WRL返回内置的winrt组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆