C++/CX での Windows ランタイム コンポーネントの作成Creating Windows Runtime Components in C++/CX

注意

このトピックは、C++/CX アプリケーションの管理ができるようにすることを目的としています。This topic exists to help you maintain your C++/CX application. ただし、新しいアプリケーションには C++/WinRT を使用することをお勧めします。But we recommend that you use C++/WinRT for new applications. C++/WinRT は Windows ランタイム (WinRT) API の標準的な最新の C++17 言語プロジェクションで、ヘッダー ファイル ベースのライブラリとして実装され、最新の Windows API への最上位アクセス権を提供するように設計されています。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. C + を使用して、Windows ランタイム コンポーネントを作成する方法について/cli WinRT を参照してくださいC + でのイベントを作成/cli WinRTします。To learn how to create a Windows Runtime Component using C++/WinRT, see Author events in C++/WinRT.

このトピックでは、C++/CX を使って Windows ランタイム コンポーネントを作成する方法を示します。このコンポーネントは、C#、Visual Basic、C++、または Javascript を使って構築したユニバーサル Windows アプリから呼び出すことができます。This topic shows how to use C++/CX to create a Windows Runtime component, which is a component that's callable from a Universal Windows app built using C#, Visual Basic, C++, or Javascript.

Windows ランタイム コンポーネントを構築するためのいくつかの理由があります。There are several reasons for building a Windows Runtime component.

  • 複雑な操作または負荷の高い操作で C++ のパフォーマンス上のメリットを得る。To get the performance advantage of C++ in complex or computationally intensive operations.
  • 既に作成されテストされている既存のコードを再利用する。To reuse code that's already written and tested.

JavaScript プロジェクトまたは .NET プロジェクト、および Windows ランタイム コンポーネント プロジェクトを含むソリューションを構築すると、JavaScript プロジェクト ファイルとコンパイル済みの DLL が 1 つのパッケージにマージされます。これを、シミュレーターを使ってローカルでデバッグしたり、テザリングされたデバイス上でリモートでデバッグしたりすることができます。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. また、拡張 SDK としてコンポーネント プロジェクトだけを配布することもできます。You can also distribute just the component project as an Extension SDK. 詳しくは、ソフトウェア開発キットの作成に関するページをご覧ください。For more information, see Creating a Software Development Kit.

一般に、コード、 C++/CX コンポーネントでは、通常を使用して、C++ライブラリと組み込み型を別の .winmd パッケージとコードの間のデータを渡している抽象バイナリ インターフェイス (ABI) の境界を除きます。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. Windows ランタイム型と、特別な構文を使用するC++/CX を作成し、それらの型の操作をサポートします。There, use Windows Runtime types and the special syntax that C++/CX supports for creating and manipulating those types. さらに、c++/cli/CX コード、JavaScript、Visual Basic、C++ では、コンポーネントから発生した処理できるイベントを実装するには、デリゲートやイベントなどの使用の種類または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#. 詳細については、C +/cli/CX 構文を参照してくださいVisual C 言語リファレンス (C +/cli CX)します。For more information about the C++/CX syntax, see Visual C++ Language Reference (C++/CX).

大文字小文字の区別と名前付け規則Casing and naming rules

JavaScriptJavaScript

JavaScript では、大文字と小文字が区別されます。JavaScript is case-sensitive. したがって、次に示す大文字小文字の区別の規則に従う必要があります。Therefore, you must follow these casing conventions:

  • C++ の名前空間とクラスを参照する場合、C++ の側と同じ大文字小文字の区別を使います。When you reference C++ namespaces and classes, use the same casing that's used on the C++ side.
  • メソッドを呼び出す場合、メソッド名が C++ の側で大文字になっていても、camel 規約に従った大文字小文字の区別を使います。When you call methods, use camel casing even if the method name is capitalized on the C++ side. たとえば、C++ のメソッド GetDate() は、JavaScript では getDate() として呼び出す必要があります。For example, a C++ method GetDate() must be called from JavaScript as getDate().
  • アクティブ化可能なクラス名や名前空間名には、UNICODE 文字を含めることはできません。An activatable class name and namespace name can't contain UNICODE characters.

.NET.NET

.NET 言語では、各言語の通常の大文字と小文字の規則が適用されます。The .NET languages follow their normal casing rules.

オブジェクトのインスタンス化Instantiating the object

Windows ランタイム型のみ ABI の境界を越えて渡すことができます。Only Windows Runtime types can be passed across the ABI boundary. コンパイラは、コンポーネントのパブリック メソッドでの戻り値の型または戻り値パラメーターが std::wstring などの型である場合、エラーを発生させます。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. Visual C++ コンポーネント拡張 (C++/CX) の組み込み型には、int や double などの通常のスカラーと、その typedef である int32、float64 などがあります。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. 詳しくは、「型システム (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();

C++/CX 組み込み型、ライブラリの型、および Windows ランタイム型C++/CX built-in types, library types, and Windows Runtime types

アクティブ化可能なクラス (ref クラスとも呼ばれます) は、JavaScript、C#、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. 他の言語から利用できるようにするには、コンポーネントに 1 個以上のアクティブ化可能なクラスを含める必要があります。To be consumable from another language, a component must contain at least one activatable class.

Windows ランタイム コンポーネントには、複数のアクティブ化可能なパブリック クラスだけでなく、コンポーネント内部でのみ認識される他のクラスも含めることができます。A Windows Runtime component can contain multiple public activatable classes as well as additional classes that are known only internally to the component. 適用、 WebHostHidden属性を C +/cli/CX 型を JavaScript に表示されるものではありません。Apply the WebHostHidden attribute to C++/CX types that are not intended to be visible to JavaScript.

すべてのパブリック クラスが、コンポーネントのメタデータ ファイルと同じ名前を持つ同じルート名前空間に存在する必要があります。All public classes must reside in the same root namespace which has the same name as the component metadata file. たとえば、A.B.C.MyClass という名前のクラスは、A.winmd、A.B.winmd、または 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. DLL の名前は .winmd ファイルの名前と一致する必要はありません。The name of the DLL is not required to match the .winmd file name.

クライアント コードでは、他のクラスと同様に、new キーワード (Visual Basic の場合は New) を使って、コンポーネントのインスタンスを作成します。Client code creates an instance of the component by using the new (New in Visual Basic) keyword just as for any class.

アクティブ化可能なクラスは public ref class sealed として宣言する必要があります。An activatable class must be declared as public ref class sealed. ref class キーワードは、Windows ランタイムと互換性のある型としてクラスを作成するようにコンパイラに指示し、sealed キーワードは、クラスが継承できないことを指定します。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. 現在、Windows ランタイムは汎用の継承モデルをサポートしていません。限定的な継承モデルによって、カスタム XAML コントロールの作成をサポートしています。The Windows Runtime does not currently support a generalized inheritance model; a limited inheritance model supports creation of custom XAML controls. 詳しくは、「Ref クラスと構造体 (C++/CX)」をご覧ください。For more information, see Ref classes and structs (C++/CX).

C++/cli CX、数値のプリミティブが既定の名前空間で定義されているすべて。For C++/CX, all the numeric primitives are defined in the default namespace. プラットフォーム名前空間を含む C +/cli CX クラス、Windows ランタイムに固有のシステムと入力します。The Platform namespace contains C++/CX classes that are specific to the Windows Runtime type system. このようなクラスには、Platform::String クラスと Platform::Object クラスがあります。These include Platform::String class and Platform::Object class. Platform::Collections::Map クラスや Platform::Collections::Vector クラスなどの具象コレクション型は、Platform::Collections 名前空間で定義されます。The concrete collection types such as Platform::Collections::Map class and Platform::Collections::Vector class are defined in the Platform::Collections namespace. これらの型によって実装されるパブリック インターフェイスは、Windows::Foundation::Collections 名前空間 (C++/CX) で定義されます。The public interfaces that these types implement are defined in Windows::Foundation::Collections Namespace (C++/CX). JavaScript、C#、および Visual Basic で利用されるのは、この種類のインターフェイスです。It is these interface types that are consumed by JavaScript, C# and Visual Basic. 詳しくは、「型システム (C++/CX)」をご覧ください。For more information, see Type System (C++/CX).

組み込み型の値を返すメソッドMethod 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;

カスタム値の構造体を返すメソッドMethod 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;}
        }
    };
}

ABI 間で、ユーザー定義の値構造体を渡すためには、C + で定義されている値構造体と同じメンバーを持つ JavaScript オブジェクトを定義/cli 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. C +、引数としてそのオブジェクトを渡すことができますし、/cli CX メソッド、オブジェクトが c++ に暗黙的に変換できるように/cli/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);
}

もう 1 つの方法は、IPropertySet を実装するクラスを定義することです (ここでは例は示されていません)。Another approach is to define a class that implements IPropertySet (not shown).

C++ で定義されている型の変数の作成だけで、.NET 言語/cli 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();
}

オーバー ロードされたメソッドOverloaded Methods

C++/cli/CX パブリック ref クラスは、オーバー ロードされたメソッドを含めることができますが、JavaScript には、オーバー ロードされたメソッドを区別する機能が制限されます。A C++/CX public ref class can contain overloaded methods, but JavaScript has limited ability to differentiate overloaded methods. たとえば、以下のシグネチャの相違を区別できます。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);
};

ただし、以下のシグネチャの相違は区別できません。But it can’t tell the difference between these:

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

あいまいな場合、JavaScript で特定のオーバーロードを常に呼び出すようにすることができます。そのためには、ヘッダー ファイルのメソッド シグネチャに Windows::Foundation::Metadata::DefaultOverload 属性を適用します。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.

次の JavaScript は、属性付きオーバーロードを常に呼び出します。This JavaScript always calls the attributed overload:

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

.NET.NET

.NET 言語認識のオーバー ロードを c++/cli 任意の .NET Framework クラスと同じように/CX ref クラスです。The .NET languages recognize overloads in a C++/CX ref class just as in any .NET Framework class.

DateTimeDateTime

Windows ランタイムでは、Windows::Foundation::DateTime オブジェクトは 1601 年 1 月 1 日の前または後の時間の長さを 100 ナノ秒単位で表した単純な 64 ビットの符号付き整数です。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. Windows:Foundation::DateTime オブジェクトには、メソッドはありません。There are no methods on a Windows:Foundation::DateTime object. 代わりに、各言語では DateTime をその言語独自の方法で算出します。JavaScript では Date オブジェクト、.NET Framework では System.DateTime 型および System.DateTimeOffset 型を利用します。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 the .NET Framework.

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

C + から DateTime 値を渡すと/cli/CX JavaScript を JavaScript 日オブジェクトとしてそれを受け入れ、既定で長い形式の日付文字列として表示されます。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;

}

.NET 言語が C + System.DateTime を通過するときに/cli CX コンポーネント、メソッドを受け入れますが、::datetime として。When a .NET language passes a System.DateTime to a C++/CX component, the method accepts it as a Windows::Foundation::DateTime. コンポーネントが .NET Framework メソッドに Windows::Foundation::DateTime を渡すと、その .NET Framework メソッドはこの値を DateTimeOffset として受け取ります。When the component passes a Windows::Foundation::DateTime to a .NET Framework 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();
}

コレクションと配列Collections and arrays

コレクションは、常に、Windows::Foundation::Collections::IVector^ や Windows::Foundation::Collections::IMap^ などの Windows ランタイム型へのハンドルとして ABI の境界を越えて渡されます。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^. たとえば、Platform::Collections::Map にハンドルを返す場合、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^. コレクション インターフェイスは c++ とは別の名前空間で定義されている/cli 具体的な実装を提供する CX クラス。The collection interfaces are defined in a namespace that's separate from the C++/CX classes that provide the concrete implementations. そのインターフェイスを JavaScript 言語と .NET 言語で利用します。JavaScript and .NET languages consume the interfaces. 詳しくは、「コレクション (C++/CX)」と「Array と WriteOnlyArray (C++/CX)」をご覧ください。For more information, see Collections (C++/CX) and Array and WriteOnlyArray (C++/CX).

IVector を渡す場合Passing 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;

.NET 言語は IVector<T> を 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();
    }
}

IMap を渡す場合Passing 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;

.NET 言語は IMap を 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();
}

プロパティProperties

パブリック ref クラス C +/cli CX コンポーネントの拡張プロパティのキーワードを使用して、プロパティとしてパブリック データ メンバーを公開します。A public ref class in C++/CX component extensions exposes public data members as properties, by using the property keyword. この概念は .NET Framework のプロパティと同じです。The concept is identical to .NET Framework properties. 単純プロパティは機能が暗黙的であるため、データ メンバーに似ています。A trivial property resembles a data member because its functionality is implicit. 非単純プロパティには、明示的な get アクセサーと set アクセサーがあり、値の "バッキング ストア" である名前付きのプライベート変数があります。A non-trivial property has explicit get and set accessors and a named private variable that's the "backing store" for the value. この例では、プライベート メンバー変数で_propertyAValue はぐるーぷのバッキング ストア。In this example, the private member variable _propertyAValue is the backing store for PropertyA. プロパティの値が変化するときにイベントを生成できます。またクライアント アプリは、そのイベントを受け取るように登録することができます。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;

.NET 言語へのアクセスのプロパティをネイティブの C +/cli CX オブジェクト、.NET Framework オブジェクトの場合と同様です。The .NET languages access properties on a native C++/CX object just as they would on a .NET Framework 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;

}

デリゲートおよびイベントDelegates and events

デリゲートは、関数オブジェクトを表す Windows ランタイム型です。A delegate is a Windows Runtime type that represents a function object. デリゲートは、後で実行するアクションを指定するために、イベント、コールバック、非同期メソッド呼び出しに関連して使います。You can use delegates in connection with events, callbacks, and asynchronous method calls to specify an action to be performed later. デリゲートは、関数オブジェクトのように、関数の戻り値の型とパラメーターの型を確認するためにコンパイラを有効にすることによってタイプ セーフを提供します。Like a function object, the delegate provides type-safety by enabling the compiler to verify the return type and parameter types of the function. デリゲートの宣言は関数のシグネチャに似ており、実装はクラス定義に、また呼び出しは関数の呼び出しに似ています。The declaration of a delegate resembles a function signature, the implementation resembles a class definition, and the invocation resembles a function invocation.

イベント リスナーの追加Adding an event listener

指定されたデリゲート型のパブリック メンバーを宣言するために event キーワードを使うことができます。You can use the event keyword to declare a public member of a specified delegate type. クライアント コードは、特定の言語に用意されている標準機能を使ってイベントをサブスクライブします。Client code subscribes to the event by using the standard mechanisms that are provided in the particular language.

public:
    event SomeHandler^ someEvent;

この例では、前のプロパティに関するセクションと同じ C++ コードを使います。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;

}

.NET 言語の場合、C++ コンポーネントのイベントをサブスクライブすることは、.NET Framework クラスのイベントをサブスクライブすることと同じです。In the .NET languages, subscribing to an event in a C++ component is the same as subscribing to an event in a .NET Framework 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();
}

1 つのイベントに複数のイベント リスナーを追加するAdding multiple event listeners for one event

JavaScript には、複数のハンドラーで単一のイベントをサブスクライブできるようにする addEventListener メソッドがあります。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 ");

C# では、前の例で示したように += 演算子を使うことで、任意の数のイベント ハンドラーがイベントをサブスクライブできるようになります。In C#, any number of event handlers can subscribe to the event by using the += operator as shown in the previous example.

列挙型Enums

C++ Windows ランタイムの列挙型/cli CX が; パブリック クラスの列挙型を使用して宣言されています。これには、標準の C++ では、スコープ列挙型に似ています。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;
};

C + 間列挙型の値で渡される/cli CX および整数としての JavaScript です。Enum values are passed between C++/CX and JavaScript as integers. C + として同じ名前付きの値を含む JavaScript オブジェクトを宣言することができます必要に応じて/cli CX 列挙型と使用としてに依存します。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# と Visual Basic のどちらの言語でも列挙型がサポートされます。Both C# and Visual Basic have language support for enums. この 2 つの言語では、.NET Framework の列挙型と同様に C ++ パブリック列挙型クラスを認識します。These languages see a C++ public enum class just as they would see a .NET Framework enum.

非同期メソッドAsynchronous methods

他の Windows ランタイム オブジェクトによって公開される非同期メソッドを利用するには、task クラス (同時実行ランタイム) を使います。To consume asynchronous methods that are exposed by other Windows Runtime objects, use the task Class (Concurrency Runtime). 詳しくは、「タスクの並列処理 (同時実行ランタイム)」をご覧ください。For more information, see and Task Parallelism (Concurrency Runtime).

C + での非同期メソッドを実装する/cli CX、使用、作成_async ppltasks.h で定義されている関数。To implement asynchronous methods in C++/CX, use the create_async function that's defined in ppltasks.h. 詳細については、次を参照してください。 c++ 非同期操作の作成/cli UWP アプリの CXします。For more information, see Creating Asynchronous Operations in C++/CX for UWP apps. 例については、次を参照してください。チュートリアル。基本的な Windows ランタイム コンポーネントを作成する c++/cli CX および JavaScript による呼び出しまたはC#します。For an example, see Walkthrough: Creating a basic Windows Runtime component in C++/CX and calling it from JavaScript or C#. .NET 言語が消費する C +/cli CX の非同期メソッドが存在している場合、.NET Framework で定義されている任意の非同期メソッドと同様です。The .NET languages consume C++/CX asynchronous methods just as they would any asynchronous method that's defined in the .NET Framework.

例外Exceptions

Windows ランタイムによって定義された任意の例外の型をスローできます。You can throw any exception type that's defined by the Windows Runtime. Windows ランタイムのどの例外の型からもカスタム型は取得できません。You cannot derive custom types from any Windows Runtime exception type. ただし、COMException をスローし、例外をキャッチするコードがアクセスできるカスタム HRESULT を提供できます。However, you can throw COMException and provide a custom HRESULT that can be accessed by the code that catches the exception. COMException でカスタム メッセージを指定する方法はありません。There's no way to specify a custom Message in a COMException.

デバッグのヒントDebugging tips

コンポーネント DLL を含む JavaScript ソリューションをデバッグするときは、コンポーネントでスクリプトのステップ実行またはネイティブ コードのステップ実行を有効にするようにデバッガーを設定できますが、この両方を同時に有効にすることはできません。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. 設定を変更するには、ソリューション エクスプローラーで JavaScript プロジェクト ノードを選んでから、[プロパティ]、[デバッグ]、[デバッガーの種類] の順に選びます。To change the setting, select the JavaScript project node in Solution Explorer and then choose Properties, Debugging, Debugger Type.

パッケージ デザイナーで必ず適切な機能を選んでください。Be sure to select appropriate capabilities in the package designer. たとえば、Windows ランタイム API を使ってユーザーの画像ライブラリにある画像ファイルを開く場合は、マニフェスト デザイナーの [機能] ウィンドウの [画像ライブラリ] チェック ボックスをオンにします。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.

JavaScript コードがコンポーネントのパブリック プロパティまたはパブリック メソッドを認識しないと考えられる場合は、JavaScript で 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. LogCalc C+ など/cli CX メソッドは、JavaScript で logCalc として参照する必要があります。For example, the LogCalc C++/CX method must be referenced as logCalc in JavaScript.

C++ を削除する場合/cli CX Windows ランタイム コンポーネント プロジェクト、ソリューションからは、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. これを行わないと、後続のデバッグまたはビルド操作が妨げられます。Failure to do so prevents subsequent debug or build operations. その後、必要に応じてアセンブリ参照を DLL に追加できます。If necessary, you can then add an assembly reference to the DLL.