如何使用WRL返回内置的winrt组件? [英] How to return a build-in winrt component using WRL?
问题描述
当我使用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 $ c命名空间(例如
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屋!