Pergunta

Quando eu criar um winrt componente usando WRL, o problema é que eu só posso usar ABI::Windows::xxx espaço de nomes, e eu não posso usar Windows::UI::Xaml::Media::Imaging espaço de nomes em WRL.

Então, como criar uma build-no winrt componente como um valor de retorno?

// 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);
    }
}
Foi útil?

Solução

Há dois conjuntos de espaços de nomes:

  • aqueles enraizada no espaço de nomes global (e.g. Windows::Foundation)
  • aqueles enraizada na ABI espaço de nomes (por exemplo, ABI::Windows::Foundation)

O conteúdo de cada um deles são "o mesmo". Por exemplo, Windows::Foundation::IUriRuntimeClass os nomes de uma mesma interface, como ABI::Windows::Foundation::IUriRuntimeClass.

Então, por que existem dois conjuntos de espaços de nomes?os espaços de nomes enraizada no espaço de nomes global são reservados para uso do C++/CX:ele gera suas projeções de classes de tempo de execução os espaços de nomes.Quando você estiver usando WRL, você vai sempre trabalhar com espaços de nomes enraizada na ABI espaço de nomes (que são o "unprojected" nomes", isto é, eles são exatamente o que existe na ABI camada).

Classes de tempo de execução são instanciados ("activo") em uma de duas maneiras.Se o tipo padrão é construível, pode ser padrão construído por chamada RoActivateInstance.Se um tipo declara outros construtores, os construtores podem ser chamados por ficar a ativação de fábrica para o tipo de tempo de execução chamando RoGetActivationFactory.Como um exemplo, você pode construir um padrão BitmapImage assim:

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 também tem uma função útil do modelo, Windows::Foundation::ActivateInstance, que chama RoActivateInstance e executa o QueryInterface para o destino desejado da interface:

using namespace Windows::Foundation;

ComPtr<IBitmapImage> bitmapImage;
if (FAILED(ActivateInstance(classId.Get(), bitmapImage.GetAddressOf())))
{
    // Handle failure
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top