次の方法で共有


Bing Maps Trip Optimizer のサンプルでの JavaScript と C++ 間の相互運用

Bing マップ トリップ オプティマイザーは、JavaScript を使用して UI と C++ を定義してトリップの最適化を実行します。このドキュメントでは、Bing マップ トリップ オプティマイザー サンプルの JavaScript および C++ の部分がどのように相互運用するかを説明します。JavaScript コンポーネントがどのように C++ コンポーネントを初期化して、そこにデータを送信するか、また C++ コンポーネントがどのように JavaScript コンポーネントにデータを戻すかを説明しています。個々の JavaScript コンポーネントおよび C++ コンポーネントの詳細については、ドキュメント「Bing Maps Trip Optimizer のサンプルでの JavaScript の使用」と「Bing Maps Trip Optimizer のサンプルでの C++ の使用」に説明されています。

注意

既に考慮しましたが、default.html、default.css、および default.js はローカル コンテキストと呼ばれます。これらのファイルが Windows ランタイム (カスタム C++ Windows ランタイム コンポーネントを含む) を参照できますが、Web にはアクセスできないからです。web.html、web.css、および web.js は Web コンテキストと呼びます。これらのファイルは Web にはアクセスできますが、Windows ランタイム にはアクセスできないためです。Web コンテキストは、ユーザー インターフェイスも定義します。

注意

このドキュメントに対応するサンプル コードは、「Bing Maps trip optimizer sample (Bing マップ トリップ オプティマイザー サンプル)」にあります。

この記事の内容

  • JavaScript から C++ コンポーネントを初期化する

  • C++ コンポーネントにデータを送信する

  • C++ コンポーネントからデータを受け取る

  • ActiveX からの移行

  • 次の手順

JavaScript から C++ コンポーネントを初期化する

ローカル コンテキストは、C++ コンポーネントと現在のトリップの最適化操作を表す変数を宣言します。

// The C++ component.
var tripOptimizer = null;

// The current asynchronous trip optimization.
var asyncOperation = null;

アプリケーションの初期化中に呼び出される optimizerLoad 関数は、TripOptimizer オブジェクトを作成します。

function optimizerLoad() {
    "use strict";
    tripOptimizer = new TripOptimizerComponent.TripOptimizer();
}

JavaScript Visual Studio プロジェクトには C++ プロジェクトへの参照が含まれているため、Windows ランタイム は TripOptimizer オブジェクトを検出して読み込むことができます。

[このページのトップへ]

C++ コンポーネントにデータを送信する

ドキュメント「Bing Maps Trip Optimizer のサンプルでの JavaScript の使用」では、Web およびローカル コンテキストがどのようにやり取りするかを示しています。ユーザーが [Get Directions] (経路の取得) または [キャンセル] ボタンをクリックすると、C++ コンポーネントの適切な TripOptimizer メソッドを呼び出すよう、Web コンテキストはローカル コンテキストにメッセージを送信します。たとえば、ユーザーが [Get Directions] (経路の取得) を選択すると、Web コンテキストはローカル コンテキストへのメッセージの一部として文字列「optimizeTrip」を送信します。ユーザーが [キャンセル] を選択すると、Web コンテキストは文字列「キャンセル」を送信します。次のコードは、ローカル コンテキストが Web コンテキストからどのようにこれらのメッセージを受け取るかを示します。

function receiveMessage(message) {
    "use strict";
    // Verify event origin.
    if (message.origin !== "ms-appx-web://microsoft.sdksamples.tripoptimizer.js") {
        return;
    }

    var data = JSON.parse(message.data);
    if (data.invoke === "load") {
        optimizerLoad();
    } else if (data.invoke === "optimizeTrip") {
        optimizerOptimizeTrip(
            data.locations,
            data.travelMode,
            data.optimize,
            data.bingMapsKey,
            data.alpha,
            data.beta,
            data.rho,
            data.iterations,
            data.parallel);
    } else if (data.invoke === "cancel") {
        optimizerCancel();
    } else if (data.invoke === "alert") {
            // Show message dialog.            
            new Windows.UI.Popups.MessageDialog(data.message).showAsync().then();
    }
}

optimizerOptimizeTrip 関数は、パラメーターを Web コンテキストから C++ コンポーネントへ転送します。

function optimizerOptimizeTrip(locations, travelMode, optimize, bingMapsKey, alpha, beta, rho, iterations, parallel) {
    "use strict";
    asyncOperation = tripOptimizer.optimizeTripAsync(locations, travelMode, optimize, bingMapsKey,
        alpha, beta, rho, iterations, parallel);

この例は、asyncOperation 変数も設定します。この変数は、ユーザーが [キャンセル] を選択すると、操作を取り消すことができるように設定します。

function optimizerCancel() {
    "use strict";
    if (asyncOperation !== null) {
        asyncOperation.cancel();
    }
}

注意

C++ コンポーネントの TripOptimizer::OptimizerTripAsync メソッドは、TripOptimizer.optimizerTripAsync として JavaScript に公開されます (JavaScript の標準の名前付け規則に合わせて、最初の文字は小文字に変更されます)。

[このページのトップへ]

C++ コンポーネントからデータを受け取る

C++ コンポーネントの TripOptimizer::OptimizerTripAsync メソッドは非同期的に動作します。そのため、アプリケーションの JavaScript の部分は、使用できるようになるとデータを処理する必要があります。JavaScript の部分は、非同期操作が完了する、エラーをスローする、または進捗状況を報告すると、約束を使用して応答します。次の例では、optimizerOptimizeTrip 関数が、TripOptimizer::OptimizeTripAsync の呼び出しの完了、エラー、および進行状況のコールバックを定義する方法を示しています。

function optimizerOptimizeTrip(locations, travelMode, optimize, bingMapsKey, alpha, beta, rho, iterations, parallel) {
    "use strict";
    asyncOperation = tripOptimizer.optimizeTripAsync(locations, travelMode, optimize, bingMapsKey,
        alpha, beta, rho, iterations, parallel);

    asyncOperation.then(
        function (result) {
            if (result !== null) {
                // If the result contains certain keys, then we know that the results contain
                // the optimize route.
                if (result.size === 2 && result.hasKey("locations") && result.hasKey("displayNames")) {
                    routeCallback(result);
                }
                    // Otherwise, we know that the component is asking us to resolve ambiguous locations.
                else {
                    locationsCallback(result);
                }
            }
            else {
                canceledCallback();
            }
            asyncOperation = null;
        },
        function (error) {
            if (error.description === "Canceled") {
                canceledCallback();
            }
            else {
                errorCallback("Error: " + error.message);
            }
            asyncOperation = null;
        },
        function (progress) {
            progressCallback(progress);
        }
        );
}

ユーザーが [キャンセル] を選択すると、C++ コンポーネントは、現在の操作を取り消すことに注意してください。ランタイムは、操作のエラー ハンドラーを呼び出します。エラーの description フィールドを「キャンセル」に設定して、結果がキャンセルによることを示します。JavaScript の非同期操作を使用する方法の詳細については、「Asynchronous programming」を参照してください。

ローカル コンテキストは、非同期操作の進行状況または結果を受け取ると、イベント データを Web コンテキストに転送し、Web コンテキストが UI を更新できるようにします。たとえば、progressCallback 関数は、Web コンテキストに送信するメッセージの一部として文字列「progressCallback」を送信します。

// Event handler for progress notifications from the Windows Runtime component.
function progressCallback(info) {
    "use strict";
    var message = { "invoke": "progressCallback", "message": info };
    window.parent.frames.mapFrame.postMessage(JSON.stringify(message), "*");
}

次の例は、Web コンテキストの receiveMessage 関数を示します。この関数は、ローカル コンテキストからメッセージを受信します。

// Receives a message from the local context.
function receiveMessage(message) {
    "use strict";
    // Verify event origin.
    if (message.origin !== "ms-appx://microsoft.sdksamples.tripoptimizer.js") {
        return;
    }

    var data = JSON.parse(message.data);
    if (data.invoke === "progressCallback") {
        progressCallback(data.message);
    } else if (data.invoke === "locationsCallback") {
        locationsCallback(JSON.parse(data.locationOptions));
    } else if (data.invoke === "routeCallback") {
        routeCallback(data.locations, data.displayNames);
    } else if (data.invoke === "canceledCallback") {
        canceledCallback();
    } else if (data.invoke === "errorCallback") {
        errorCallback(data.message);
    }
}

「progressCallback」のメッセージでは、Web コンテキストは progressCallback 関数を呼び出し、この関数は進行状況メッセージを表示するために UI を更新します。

// Event handler for progress notifications from the control.
function progressCallback(message) {
    "use strict";
    // Set message.
    progressMessageText.innerHTML = message;
}

[このページのトップへ]

ActiveX からの移行

Bing マップ トリップ オプティマイザーの ActiveX バージョンから Windows ストア アプリへの移行に関する詳細については、「Bing Maps Trip Optimizer のサンプルでの既存のコードの移行」を参照してください。

[このページのトップへ]

次の手順

この記事では、JavaScript および C++ を使用して完全な Windows ストア アプリケーションを作成する方法について説明しました。JavaScript アプリケーションと共に C++ コンポーネントを使用して、既に記述したコードを有効活用し、パフォーマンスを向上させることができます。

[このページのトップへ]