Componentes do Windows Runtime com C++/CXWindows Runtime components with C++/CX

Observação

Este tópico existe para ajudar você na manutenção do seu aplicativo C++/CX.This topic exists to help you maintain your C++/CX application. Recomendamos que você use C++/WinRT para novos aplicativos.But we recommend that you use C++/WinRT for new applications. C++/WinRT é uma projeção de linguagem C++17 completamente moderna e padrão para APIs do WinRT (Windows Runtime), implementada como uma biblioteca com base em cabeçalho e arquivo, projetada para fornecer acesso de primeira classe à API moderna do Windows.C++/WinRT is an entirely standard modern C++17 language projection for Windows Runtime (WinRT) APIs, implemented as a header-file-based library, and designed to provide you with first-class access to the modern Windows API. Para aprender a criar um componente do Windows Runtime usando C++/WinRT, confira Componentes do Windows Runtime com C++/WinRT.To learn how to create a Windows Runtime component using C++/WinRT, see Windows Runtime components with C++/WinRT.

Este tópico mostra como usar C++/CX para criar um componente de Windows Runtime — um componente que possa ser chamado de um aplicativo universal do Windows criado usando qualquer linguagem de Windows Runtime (C#, Visual Basic, C++ ou JavaScript).This topic shows how to use C++/CX to create a Windows Runtime component—a component that's callable from a Universal Windows app built using any Windows Runtime language (C#, Visual Basic, C++, or Javascript).

Há vários motivos para criar um componente de Windows Runtime em C++.There are several reasons for building a Windows Runtime component in C++.

  • Obter a vantagem em termos de desempenho do C++ em operações complexas ou intensivas.To get the performance advantage of C++ in complex or computationally intensive operations.
  • Reutilizar um código que já tenha sido escrito e testado.To reuse code that's already written and tested.

Quando você compila uma solução que contém um projeto JavaScript ou .NET e um projeto de componente do Tempo de Execução do Windows, os arquivos de projeto JavaScript e a DLL compilada são mesclados em um único pacote, que é possível depurar localmente no simulador ou remotamente em um dispositivo vinculado.When you build a solution that contains a JavaScript or .NET project, and a Windows Runtime component project, the JavaScript project files and the compiled DLL are merged into one package, which you can debug locally in the simulator or remotely on a tethered device. Também é possível distribuir apenas o projeto de componente como um SDK de extensão.You can also distribute just the component project as an Extension SDK. Para obter mais informações, consulte Criando um Software Development Kit.For more information, see Creating a Software Development Kit.

Em geral, ao codificar seu componente C++/CX, use a biblioteca C++ regular e os tipos internos, exceto no limite da ABI (interface binária abstrata) em que você está passando dados de e para o código em outro pacote de winmd.In general, when you code your C++/CX component, use the regular C++ library and built-in types, except at the abstract binary interface (ABI) boundary where you are passing data to and from code in another .winmd package. Lá, use Windows Runtime tipos e a sintaxe especial que o C++/CX suporta para criar e manipular esses tipos.There, use Windows Runtime types and the special syntax that C++/CX supports for creating and manipulating those types. Além disso, no código C++/CX, use tipos como delegado e evento para implementar eventos que podem ser gerados a partir de seu componente e tratados em JavaScript, Visual Basic, C++ ou C#.In addition, in your C++/CX code, use types such as delegate and event to implement events that can be raised from your component and handled in JavaScript, Visual Basic, C++, or C#. Para obter mais informações sobre a sintaxe C++/CX, consulte referência de linguagem de Visual C++ (C++/CX).For more information about the C++/CX syntax, see Visual C++ Language Reference (C++/CX).

Uso de maiúsculas e regras de nomenclaturaCasing and naming rules

JavaScriptJavaScript

JavaScript diferencia maiúsculas de minúsculas.JavaScript is case-sensitive. Portanto, você deve seguir estas convenções do uso de maiúsculas:Therefore, you must follow these casing conventions:

  • Ao fazer referência a namespaces e classes C++, siga o uso de maiúsculas no lado de C++.When you reference C++ namespaces and classes, use the same casing that's used on the C++ side.
  • Ao chamar métodos, siga o uso de maiúsculas camel mesmo que o nome do método esteja em maiúsculas no lado de C++.When you call methods, use camel casing even if the method name is capitalized on the C++ side. Por exemplo, um método C++ GetDate() deve ser chamado em JavaScript como getDate().For example, a C++ method GetDate() must be called from JavaScript as getDate().
  • Um nome de classe ativável e o nome de namespace não podem conter caracteres UNICODE.An activatable class name and namespace name can't contain UNICODE characters.

.NET.NET

As linguagens .NET seguem as regras do uso de maiúsculas normal.The .NET languages follow their normal casing rules.

Criação de instância do objetoInstantiating the object

Somente os tipos do Windows Runtime podem cruzar o limite ABI.Only Windows Runtime types can be passed across the ABI boundary. O compilador acionará um erro se o componente tiver um tipo como std::wstring como um tipo de retorno ou parâmetro em um método público.The compiler will raise an error if the component has a type like std::wstring as a return type or parameter in a public method. Os tipos internos de extensões de componente do Visual C++ (C++/CX) incluem os escalares usuais, como int e double, além dos equivalentes typedef int32, float64, etc.The Visual C++ component extensions (C++/CX) built-in types include the usual scalars such as int and double, and also their typedef equivalents int32, float64, and so on. Para obter mais informações, consulte Sistema de Tipos (C++/CX).For more information, see Type System (C++/CX).

// ref class definition in C++
public ref class SampleRefClass sealed
{
    // Class members...

    // #include <valarray>
public:
    double LogCalc(double input)
    {
        // Use C++ standard library as usual.
        return std::log(input);
    }

};
//Instantiation in JavaScript (requires "Add reference > Project reference")
var nativeObject = new CppComponent.SampleRefClass();
//Call a method and display result in a XAML TextBlock
var num = nativeObject.LogCalc(21.5);
ResultText.Text = num.ToString();

Tipos internos de C++/CX, tipos de biblioteca e tipos de Windows RuntimeC++/CX built-in types, library types, and Windows Runtime types

Uma classe ativável (também conhecida como uma classe ref) é aquela cuja instância é criada com base em outra linguagem, como JavaScript, C# ou Visual Basic.An activatable class (also known as a ref class) is one that can be instantiated from another language such as JavaScript, C# or Visual Basic. Para ser consumível em outra linguagem, um componente deve conter pelo menos uma classe ativável.To be consumable from another language, a component must contain at least one activatable class.

Um componente do Tempo de Execução do Windows pode conter várias classes ativáveis públicas, bem como classes adicionais que são conhecidas apenas internamente para o componente.A Windows Runtime component can contain multiple public activatable classes as well as additional classes that are known only internally to the component. Aplique o atributo WebHostHidden a tipos C++/CX que não devem ser visíveis para JavaScript.Apply the WebHostHidden attribute to C++/CX types that are not intended to be visible to JavaScript.

Todas as classes públicas devem residir no mesmo namespace raiz com o mesmo nome do arquivo de metadados do componente.All public classes must reside in the same root namespace which has the same name as the component metadata file. Por exemplo, uma classe denominada A.B.C.MyClass poderá ser instanciada somente se for definida em um arquivo de metadados denominado A.winmd ou A.B.winmd ou A.B.C.winmd.For example, a class that's named A.B.C.MyClass can be instantiated only if it's defined in a metadata file that's named A.winmd or A.B.winmd or A.B.C.winmd. O nome da DLL não precisa coincidir com o nome do arquivo .winmd.The name of the DLL is not required to match the .winmd file name.

O código do cliente cria uma instância do componente usando a palavra-chave new (New em Visual Basic) assim como acontece com qualquer classe.Client code creates an instance of the component by using the new (New in Visual Basic) keyword just as for any class.

Uma classe ativável deve ser declarada como classe ref pública selado.An activatable class must be declared as public ref class sealed. A palavra-chave ref class informa ao compilador para criar a classe como um tipo compatível do Windows Runtime e a palavra-chave sealed especifica que a classe não pode ser herdada.The ref class keyword tells the compiler to create the class as a Windows Runtime compatible type, and the sealed keyword specifies that the class cannot be inherited. O Windows Runtime não dá suporte no momento a um modelo de herança generalizado; um modelo de herança limitado dá suporte à criação de controles XAML personalizados.The Windows Runtime does not currently support a generalized inheritance model; a limited inheritance model supports creation of custom XAML controls. Para obter mais informações, consulte Classes e estruturas de referência (C++/CX).For more information, see Ref classes and structs (C++/CX).

Para C++/CX, todos os primitivos numéricos são definidos no namespace padrão.For C++/CX, all the numeric primitives are defined in the default namespace. O namespace de plataforma contém classes C++/CX que são específicas para o sistema de tipo de Windows Runtime.The Platform namespace contains C++/CX classes that are specific to the Windows Runtime type system. Isso inclui as classes Platform::String e Platform::Object.These include Platform::String class and Platform::Object class. Os tipos de coleção concretos como as classes Platform::Collections::Map e Platform::Collections::Vector são definidos no namespace Platform::Collections.The concrete collection types such as Platform::Collections::Map class and Platform::Collections::Vector class are defined in the Platform::Collections namespace. As interfaces públicas que esses tipos implementam são definidas no Namespace Windows::Foundation::Collections (C++/CX).The public interfaces that these types implement are defined in Windows::Foundation::Collections Namespace (C++/CX). São esses tipos de interface consumidos por JavaScript, C# e Visual Basic.It is these interface types that are consumed by JavaScript, C# and Visual Basic. Para obter mais informações, consulte Sistema de Tipos (C++/CX).For more information, see Type System (C++/CX).

Método que retorna um valor de tipo internoMethod that returns a value of built-in type

    // #include <valarray>
public:
    double LogCalc(double input)
    {
        // Use C++ standard library as usual.
        return std::log(input);
    }
//Call a method
var nativeObject = new CppComponent.SampleRefClass;
var num = nativeObject.logCalc(21.5);
document.getElementById('P2').innerHTML = num;

Método que retorna uma estrutura de valor personalizadaMethod that returns a custom value struct

namespace CppComponent
{
    // Custom struct
    public value struct PlayerData
    {
        Platform::String^ Name;
        int Number;
        double ScoringAverage;
    };

    public ref class Player sealed
    {
    private:
        PlayerData m_player;
    public:
        property PlayerData PlayerStats
        {
            PlayerData get(){ return m_player; }
            void set(PlayerData data) {m_player = data;}
        }
    };
}

Para passar structs de valor definido pelo usuário pela ABI, defina um objeto JavaScript que tenha os mesmos membros que o struct de valor definido em C++/CX.To pass user-defined value structs across the ABI, define a JavaScript object that has the same members as the value struct that's defined in C++/CX. Em seguida, você pode passar esse objeto como um argumento para um método C++/CX para que o objeto seja convertido implicitamente no tipo C++/CX.You can then pass that object as an argument to a C++/CX method so that the object is implicitly converted to the C++/CX type.

// Get and set the value struct
function GetAndSetPlayerData() {
    // Create an object to pass to C++
    var myData =
        { name: "Bob Homer", number: 12, scoringAverage: .357 };
    var nativeObject = new CppComponent.Player();
    nativeObject.playerStats = myData;

    // Retrieve C++ value struct into new JavaScript object
    var myData2 = nativeObject.playerStats;
    document.getElementById('P3').innerHTML = myData.name + " , " + myData.number + " , " + myData.scoringAverage.toPrecision(3);
}

Outra abordagem é definir uma classe que implemente IPropertySet (não mostrado).Another approach is to define a class that implements IPropertySet (not shown).

Nas linguagens do .NET, basta criar uma variável do tipo definido no componente C++/CX.In the .NET languages, you just create a variable of the type that's defined in the C++/CX component.

private void GetAndSetPlayerData()
{
    // Create a ref class
    var player = new CppComponent.Player();

    // Create a variable of a value struct
    // type that is defined in C++
    CppComponent.PlayerData myPlayer;
    myPlayer.Name = "Babe Ruth";
    myPlayer.Number = 12;
    myPlayer.ScoringAverage = .398;

    // Set the property
    player.PlayerStats = myPlayer;

    // Get the property and store it in a new variable
    CppComponent.PlayerData myPlayer2 = player.PlayerStats;
    ResultText.Text += myPlayer.Name + " , " + myPlayer.Number.ToString() +
        " , " + myPlayer.ScoringAverage.ToString();
}

Métodos sobrecarregadosOverloaded Methods

Uma classe ref pública C++/CX pode conter métodos sobrecarregados, mas o JavaScript tem capacidade limitada de diferenciar métodos sobrecarregados.A C++/CX public ref class can contain overloaded methods, but JavaScript has limited ability to differentiate overloaded methods. Por exemplo, ele pode informar a diferença entre essas assinaturas:For example, it can tell the difference between these signatures:

public ref class NumberClass sealed
{
public:
    int GetNumber(int i);
    int GetNumber(int i, Platform::String^ str);
    double GetNumber(int i, MyData^ d);
};

Mas não pode dizer a diferença entre eles:But it can't tell the difference between these:

int GetNumber(int i);
double GetNumber(double d);

Em casos ambíguos, é possível garantir que o JavaScript sempre chame uma sobrecarga específica aplicando o atributo Windows::Foundation::Metadata::DefaultOverload à assinatura do método no arquivo de cabeçalho.In ambiguous cases, you can ensure that JavaScript always calls a specific overload by applying the Windows::Foundation::Metadata::DefaultOverload attribute to the method signature in the header file.

Esse JavaScript sempre chama a sobrecarga atribuída:This JavaScript always calls the attributed overload:

var nativeObject = new CppComponent.NumberClass();
var num = nativeObject.getNumber(9);
document.getElementById('P4').innerHTML = num;

.NET.NET

As linguagens .NET reconhecem sobrecargas em uma classe ref C++/CX, assim como em qualquer classe .NET.The .NET languages recognize overloads in a C++/CX ref class just as in any .NET class.

DatetimeDateTime

No Windows Runtime, um objeto Windows::Foundation::DateTime é apenas um inteiro assinado de 64 bits que representa o número de intervalos de 100 nanossegundos antes ou depois de 1° de janeiro de 1601.In the Windows Runtime, a Windows::Foundation::DateTime object is just a 64-bit signed integer that represents the number of 100-nanosecond intervals either before or after January 1, 1601. Não há método em um objeto Windows:Foundation::DateTime.There are no methods on a Windows:Foundation::DateTime object. Em vez disso, cada linguagem projeta o DateTime na forma que é nativa a esse idioma: o objeto Date em JavaScript e os tipos System. DateTime e System. DateTimeOffset no .NET.Instead, each language projects the DateTime in the way that is native to that language: the Date object in JavaScript and the System.DateTime and System.DateTimeOffset types in .NET.

public  ref class MyDateClass sealed
{
public:
    property Windows::Foundation::DateTime TimeStamp;
    void SetTime(Windows::Foundation::DateTime dt)
    {
        auto cal = ref new Windows::Globalization::Calendar();
        cal->SetDateTime(dt);
        TimeStamp = cal->GetDateTime(); // or TimeStamp = dt;
    }
};

Quando você passa um valor DateTime de C++/CX para JavaScript, o JavaScript o aceita como um objeto Date e o exibe por padrão como uma cadeia de caracteres de data de forma longa.When you pass a DateTime value from C++/CX to JavaScript, JavaScript accepts it as a Date object and displays it by default as a long-form date string.

function SetAndGetDate() {
    var nativeObject = new CppComponent.MyDateClass();

    var myDate = new Date(1956, 4, 21);
    nativeObject.setTime(myDate);

    var myDate2 = nativeObject.timeStamp;

    //prints long form date string
    document.getElementById('P5').innerHTML = myDate2;

}

Quando uma linguagem .NET passa um System. DateTime para um componente C++/CX, o método o aceita como um Windows:: Foundation::D ateTime.When a .NET language passes a System.DateTime to a C++/CX component, the method accepts it as a Windows::Foundation::DateTime. Quando o componente passa um Windows:: Foundation::D ateTime para um método .NET, o método de estrutura o aceita como um DateTimeOffset.When the component passes a Windows::Foundation::DateTime to a .NET method, the Framework method accepts it as a DateTimeOffset.

private void DateTimeExample()
{
    // Pass a System.DateTime to a C++ method
    // that takes a Windows::Foundation::DateTime
    DateTime dt = DateTime.Now;
    var nativeObject = new CppComponent.MyDateClass();
    nativeObject.SetTime(dt);

    // Retrieve a Windows::Foundation::DateTime as a
    // System.DateTimeOffset
    DateTimeOffset myDate = nativeObject.TimeStamp;

    // Print the long-form date string
    ResultText.Text += myDate.ToString();
}

Coleções e matrizesCollections and arrays

Coleções sempre passam o limite da ABI como identificadores para tipos do Windows Runtime, como Windows::Foundation::Collections::IVector^ e Windows::Foundation::Collections::IMap^.Collections are always passed across the ABI boundary as handles to Windows Runtime types such as Windows::Foundation::Collections::IVector^ and Windows::Foundation::Collections::IMap^. Por exemplo, caso você retorne um identificador para um Platform::Collections::Map, ele é convertido implicitamente em Windows::Foundation::Collections::IMap^.For example, if you return a handle to a Platform::Collections::Map, it implicitly converts to a Windows::Foundation::Collections::IMap^. As interfaces de coleção são definidas em um namespace separado das classes C++/CX que fornecem as implementações concretas.The collection interfaces are defined in a namespace that's separate from the C++/CX classes that provide the concrete implementations. As linguagens JavaScript e .NET consomem as interfaces.JavaScript and .NET languages consume the interfaces. Para obter mais informações, consulte Coleções (C++/CX) e Array e WriteOnlyArray (C++/CX).For more information, see Collections (C++/CX) and Array and WriteOnlyArray (C++/CX).

Passagem de IVectorPassing IVector

// Windows::Foundation::Collections::IVector across the ABI.
//#include <algorithm>
//#include <collection.h>
Windows::Foundation::Collections::IVector<int>^ SortVector(Windows::Foundation::Collections::IVector<int>^ vec)
{
    std::sort(begin(vec), end(vec));
    return vec;
}
var nativeObject = new CppComponent.CollectionExample();
// Call the method to sort an integer array
var inVector = [14, 12, 45, 89, 23];
var outVector = nativeObject.sortVector(inVector);
var result = "Sorted vector to array:";
for (var i = 0; i < outVector.length; i++)
{
    outVector[i];
    result += outVector[i].toString() + ",";
}
document.getElementById('P6').innerHTML = result;

As linguagens .NET consideram IVector<T> como IList<T>.The .NET languages see IVector<T> as IList<T>.

private void SortListItems()
{
    IList<int> myList = new List<int>();
    myList.Add(5);
    myList.Add(9);
    myList.Add(17);
    myList.Add(2);

    var nativeObject = new CppComponent.CollectionExample();
    IList<int> mySortedList = nativeObject.SortVector(myList);

    foreach (var item in mySortedList)
    {
        ResultText.Text += " " + item.ToString();
    }
}

Passagem de IMapPassing IMap

// #include <map>
//#include <collection.h>
Windows::Foundation::Collections::IMap<int, Platform::String^> ^GetMap(void)
{    
    Windows::Foundation::Collections::IMap<int, Platform::String^> ^ret =
        ref new Platform::Collections::Map<int, Platform::String^>;
    ret->Insert(1, "One ");
    ret->Insert(2, "Two ");
    ret->Insert(3, "Three ");
    ret->Insert(4, "Four ");
    ret->Insert(5, "Five ");
    return ret;
}
// Call the method to get the map
var outputMap = nativeObject.getMap();
var mStr = "Map result:" + outputMap.lookup(1) + outputMap.lookup(2)
    + outputMap.lookup(3) + outputMap.lookup(4) + outputMap.lookup(5);
document.getElementById('P7').innerHTML = mStr;

As linguagens .NET consideram IMap e IDictionary<K, V>.The .NET languages see IMap and IDictionary<K, V>.

private void GetDictionary()
{
    var nativeObject = new CppComponent.CollectionExample();
    IDictionary<int, string> d = nativeObject.GetMap();
    ResultText.Text += d[2].ToString();
}

PropriedadesProperties

Uma classe ref pública em extensões de componente C++/CX expõe membros de dados públicos como propriedades, usando a palavra-chave Property.A public ref class in C++/CX component extensions exposes public data members as properties, by using the property keyword. O conceito é idêntico às propriedades do .NET.The concept is identical to .NET properties. Uma propriedade trivial se parece com um membro de dados porque a funcionalidade é implícita.A trivial property resembles a data member because its functionality is implicit. Uma propriedade não trivial tem acessadores get e set explícitos e uma variável privada nomeada que é o "armazenamento de backup" para o valor.A non-trivial property has explicit get and set accessors and a named private variable that's the "backing store" for the value. Neste exemplo, a variável de membro particular _ propertyAValue é o repositório de backup da propriedadeA.In this example, the private member variable _propertyAValue is the backing store for PropertyA. Uma propriedade pode acionar um evento quando o valor é alterado e um aplicativo cliente pode se registrar para receber esse evento.A property can fire an event when its value changes, and a client app can register to receive that event.

//Properties
public delegate void PropertyChangedHandler(Platform::Object^ sender, int arg);
public ref class PropertyExample  sealed
{
public:
    PropertyExample(){}

    // Event that is fired when PropertyA changes
    event PropertyChangedHandler^ PropertyChangedEvent;

    // Property that has custom setter/getter
    property int PropertyA
    {
        int get() { return m_propertyAValue; }
        void set(int propertyAValue)
        {
            if (propertyAValue != m_propertyAValue)
            {
                m_propertyAValue = propertyAValue;
                // Fire event. (See event example below.)
                PropertyChangedEvent(this, propertyAValue);
            }
        }
    }

    // Trivial get/set property that has a compiler-generated backing store.
    property Platform::String^ PropertyB;

private:
    // Backing store for propertyA.
    int m_propertyAValue;
};
var nativeObject = new CppComponent.PropertyExample();
var propValue = nativeObject.propertyA;
document.getElementById('P8').innerHTML = propValue;

//Set the string property
nativeObject.propertyB = "What is the meaning of the universe?";
document.getElementById('P9').innerHTML += nativeObject.propertyB;

As linguagens .NET acessam Propriedades em um objeto C++/CX nativo, assim como fariam em um objeto .NET.The .NET languages access properties on a native C++/CX object just as they would on a .NET object.

private void GetAProperty()
{
    // Get the value of the integer property
    // Instantiate the C++ object
    var obj = new CppComponent.PropertyExample();

    // Get an integer property
    var propValue = obj.PropertyA;
    ResultText.Text += propValue.ToString();

    // Set a string property
    obj.PropertyB = " What is the meaning of the universe?";
    ResultText.Text += obj.PropertyB;

}

Representantes e eventosDelegates and events

Um representante é um tipo do Windows Runtime que representa um objeto de função.A delegate is a Windows Runtime type that represents a function object. É possível usar representantes em relação a eventos, retornos de chamada e chamadas de método assíncrono para especificar uma ação a ser realizada posteriormente.You can use delegates in connection with events, callbacks, and asynchronous method calls to specify an action to be performed later. Assim como um objeto de função, o representante fornece segurança de tipo, permitindo que o compilador verifique o tipo de retorno e os tipos de parâmetro da função.Like a function object, the delegate provides type-safety by enabling the compiler to verify the return type and parameter types of the function. A declaração de um representante se parece com uma assinatura de função, a implementação é semelhante a uma definição de classe e a invocação se parece com uma chamada de função.The declaration of a delegate resembles a function signature, the implementation resembles a class definition, and the invocation resembles a function invocation.

Adição de um ouvinte de eventosAdding an event listener

É possível pode usar a palavra-chave event para declarar um membro público de um tipo representante especificado.You can use the event keyword to declare a public member of a specified delegate type. O código do cliente se inscreve no evento usando os mecanismos padrão fornecidos na linguagem específica.Client code subscribes to the event by using the standard mechanisms that are provided in the particular language.

public:
    event SomeHandler^ someEvent;

Este exemplo usa o mesmo código C++ da seção de propriedades anterior.This example uses the same C++ code as for the previous properties section.

function Button_Click() {
    var nativeObj = new CppComponent.PropertyExample();
    // Define an event handler method
    var singlecasthandler = function (ev) {
        document.getElementById('P10').innerHTML = "The button was clicked and the value is " + ev;
    };

    // Subscribe to the event
    nativeObj.onpropertychangedevent = singlecasthandler;

    // Set the value of the property and fire the event
    var propValue = 21;
    nativeObj.propertyA = 2 * propValue;

}

Nas linguagens .NET, assinar um evento em um componente C++ é o mesmo que assinar um evento em uma classe .NET:In the .NET languages, subscribing to an event in a C++ component is the same as subscribing to an event in a .NET class:

//Subscribe to event and call method that causes it to be fired.
private void TestMethod()
{
    var objWithEvent = new CppComponent.PropertyExample();
    objWithEvent.PropertyChangedEvent += objWithEvent_PropertyChangedEvent;

    objWithEvent.PropertyA = 42;
}

//Event handler method
private void objWithEvent_PropertyChangedEvent(object __param0, int __param1)
{
    ResultText.Text = "the event was fired and the result is " +
         __param1.ToString();
}

Adição de vários ouvintes de eventos para um eventoAdding multiple event listeners for one event

JavaScript tem um método addEventListener que permite que vários manipuladores se inscrevam em um único evento.JavaScript has an addEventListener method that enables multiple handlers to subscribe to a single event.

public delegate void SomeHandler(Platform::String^ str);

public ref class LangSample sealed
{
public:
    event SomeHandler^ someEvent;
    property Platform::String^ PropertyA;

    // Method that fires an event
    void FireEvent(Platform::String^ str)
    {
        someEvent(Platform::String::Concat(str, PropertyA->ToString()));
    }
    //...
};
// Add two event handlers
var multicast1 = function (ev) {
    document.getElementById('P11').innerHTML = "Handler 1: " + ev.target;
};
var multicast2 = function (ev) {
    document.getElementById('P12').innerHTML = "Handler 2: " + ev.target;
};

var nativeObject = new CppComponent.LangSample();
//Subscribe to the same event
nativeObject.addEventListener("someevent", multicast1);
nativeObject.addEventListener("someevent", multicast2);

nativeObject.propertyA = "42";

// This method should fire an event
nativeObject.fireEvent("The answer is ");

Em C#, qualquer número de manipuladores de eventos pode se inscrever no evento usando o operador += conforme mostrado no exemplo anterior.In C#, any number of event handlers can subscribe to the event by using the += operator as shown in the previous example.

EnumsEnums

Uma Windows Runtime enumeração em C++/CX é declarada usando enum de classe pública; Ele é semelhante a uma enumeração com escopo no C++ padrão.A Windows Runtime enum in C++/CX is declared by using public class enum; it resembles a scoped enum in standard C++.

public enum class Direction {North, South, East, West};

public ref class EnumExampleClass sealed
{
public:
    property Direction CurrentDirection
    {
        Direction  get(){return m_direction; }
    }

private:
    Direction m_direction;
};

Os valores de enumeração são passados entre C++/CX e JavaScript como inteiros.Enum values are passed between C++/CX and JavaScript as integers. Opcionalmente, você pode declarar um objeto JavaScript que contém os mesmos valores nomeados que o enum C++/CX e usá-lo da seguinte maneira.You can optionally declare a JavaScript object that contains the same named values as the C++/CX enum and use it as follows.

var Direction = { 0: "North", 1: "South", 2: "East", 3: "West" };
//. . .

var nativeObject = new CppComponent.EnumExampleClass();
var curDirection = nativeObject.currentDirection;
document.getElementById('P13').innerHTML =
Direction[curDirection];

C# e Visual Basic têm suporte de linguagem para enumerações.Both C# and Visual Basic have language support for enums. Esses idiomas veem uma classe de enumeração pública do C++ assim como veriam um enum .NET.These languages see a C++ public enum class just as they would see a .NET enum.

Métodos assíncronosAsynchronous methods

Para consumir métodos assíncronos expostos por outros objetos do Windows Runtime, use a Classe task (Tempo de Execução de Simultaneidade).To consume asynchronous methods that are exposed by other Windows Runtime objects, use the task Class (Concurrency Runtime). Para obter mais informações, consulte Paralelismo de tarefas (Tempo de Execução de Simultaneidade).For more information, see and Task Parallelism (Concurrency Runtime).

Para implementar métodos assíncronos no C++/CX, use a função Create _ Async definida em ppltasks. h.To implement asynchronous methods in C++/CX, use the create_async function that's defined in ppltasks.h. Para obter mais informações, consulte criando operações assíncronas em C++/CX para aplicativos UWP.For more information, see Creating Asynchronous Operations in C++/CX for UWP apps. Para obter um exemplo, consulte passo a passos de criando um componente de Windows Runtime C++/CX e chamando-o do JavaScript ou C#.For an example, see Walkthrough of creating a C++/CX Windows Runtime component, and calling it from JavaScript or C#. As linguagens .NET consomem métodos assíncronos C++/CX da mesma forma que fariam com qualquer método assíncrono definido no .NET.The .NET languages consume C++/CX asynchronous methods just as they would any asynchronous method that's defined in .NET.

ExceçõesExceptions

É possível acionar qualquer tipo de exceção definido pelo Windows Runtime.You can throw any exception type that's defined by the Windows Runtime. Não é possível derivar tipos personalizados de qualquer tipo de exceção do Windows Runtime.You cannot derive custom types from any Windows Runtime exception type. No entanto, é possível acionar COMException e fornecer um HRESULT personalizado que pode ser acessado pelo código que captura a exceção.However, you can throw COMException and provide a custom HRESULT that can be accessed by the code that catches the exception. Não existe uma maneira de especificar uma mensagem personalizada em um COMException.There's no way to specify a custom Message in a COMException.

Dicas de depuraçãoDebugging tips

Ao depurar uma solução JavaScript com uma DLL de componente, você pode definir o depurador para habilitar a passagem pelo script ou a passagem pelo código nativo no componente, mas não ambos ao mesmo tempo.When you debug a JavaScript solution that has a component DLL, you can set the debugger to enable either stepping through script, or stepping through native code in the component, but not both at the same time. Para alterar a configuração, selecione o nó do projeto JavaScript no Gerenciador de Soluções e escolha Propriedades, Depuração, Tipo de Depurador.To change the setting, select the JavaScript project node in Solution Explorer and then choose Properties, Debugging, Debugger Type.

Não se esqueça de selecionar os recursos apropriados no designer do pacote.Be sure to select appropriate capabilities in the package designer. Por exemplo, caso você esteja tentando abrir um arquivo de imagem na biblioteca de imagens do usuário usando as APIs do Windows Runtime, assegure-se de marcar a caixa de seleção Biblioteca de Imagens no painel Funcionalidades do designer de manifesto.For example, if you are attempting to open an image file in the user's Pictures library by using the Windows Runtime APIs, be sure to select the Pictures Library check box in the Capabilities pane of the manifest designer.

Caso o código JavaScript aparentemente não reconheça as propriedades públicas ou os métodos no componente, assegure-se de que, no JavaScript, você esteja seguindo o uso de maiúsculas camel.If your JavaScript code doesn't seem to be recognizing the public properties or methods in the component, make sure that in JavaScript you are using camel casing. Por exemplo, o método LogCalc C++/CX deve ser referenciado como logCalc em JavaScript.For example, the LogCalc C++/CX method must be referenced as logCalc in JavaScript.

Se você remover um projeto de componente Windows Runtime do C++/CX de uma solução, você também deverá remover manualmente a referência do projeto do projeto JavaScript.If you remove a C++/CX Windows Runtime component project from a solution, you must also manually remove the project reference from the JavaScript project. Deixar de fazer isso impede operações de depuração ou compilação subsequentes.Failure to do so prevents subsequent debug or build operations. Caso necessário, é possível adicionar uma referência de assembly à DLL.If necessary, you can then add an assembly reference to the DLL.