Interopérabilité entre JavaScript et C++ dans l'exemple de l'optimiseur de voyage Bing Maps

L'optimiseur de voyage Bing Maps utilise JavaScript utilise pour définir l'interface utilisateur et C++ pour exécuter l'optimisation du voyage. Ce document décrit comment les composants JavaScript et C++ de l'exemple Optimiseur de voyage Bing Maps interagissent. Il présente comment le composant JavaScript initialise le composant C++ et lui envoie des données et comment le composant C++ renvoie des données au composant JavaScript. Les différents composants JavaScript et C++ sont décrits plus en détail dans les documents Utilisation de JavaScript dans l'exemple de l'optimiseur de voyage Bing Maps et Utilisation de C++ dans l'exemple de l'optimiseur de voyage Bing Maps.

Notes

N'oubliez pas que default.html, default.css et default.js sont désignés comme le contexte local car ces fichiers peuvent référencer le Windows Runtime (notamment le composant Windows Runtime C++ personnalisé), mais ne peuvent pas accéder au Web. web.html, web.css et web.js sont désignés comme le contexte Web car ces fichiers peuvent accéder au Web mais ne peuvent pas accéder au Windows Runtime. Le contexte Web définit également l'interface utilisateur.

Notes

L'exemple de code qui correspond à ce document se trouve dans l'Exemple Optimiseur de voyage Bing Maps.

Dans cet article

  • Initialisation du composant C++ à partir de JavaScript

  • Envoi de données au composant C++

  • Réception de données depuis le composant C++

  • Migration à partir d'ActiveX

  • Étapes suivantes

Initialisation du composant C++ à partir de JavaScript

Le contexte local déclare les variables qui représentent le composant C++ et l'optimisation de voyage actuelle.

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

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

La fonction optimizerLoad, qui est appelée pendant l'initialisation de l'application, crée l'objet TripOptimizer.

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

Le Windows Runtime peut rechercher et charger l'objet TripOptimizer car le projet Visual Studio JavaScript contient une référence au projet C++.

[Haut]

Envoi de données au composant C++

Le document Utilisation de JavaScript dans l'exemple de l'optimiseur de voyage Bing Maps décrit comment le contexte Web et le contexte local communiquent. Lorsque l'utilisateur sélectionne le bouton Get Directions ou Cancel, le contexte Web envoie un message au contexte local pour appeler la méthode appropriée TripOptimizer du composant C++. Par exemple, lorsque l'utilisateur choisit Get Directions, le contexte Web envoie la chaîne « optimizeTrip » dans le cadre du message au contexte local. Lorsque l'utilisateur choisit Cancel, le contexte Web envoie la chaîne « cancel ». Le code suivant montre comment le contexte local reçoit ces messages du contexte 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();
    }
}

La fonction optimizerOptimizeTrip transfert les paramètres du contexte Web au composant 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);

Cet exemple définit également la variable asyncOperation. Cette variable est définie pour pouvoir annuler l'opération lorsque l'utilisateur choisit Cancel.

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

Notes

La méthode TripOptimizer::OptimizerTripAsync du composant C++ est exposée à JavaScript en tant que TripOptimizer.optimizerTripAsync (la première lettre est remplacée par une minuscule pour respecter les conventions d'affectation de noms standard JavaScript).

[Haut]

Réception de données depuis le composant C++

La méthode TripOptimizer::OptimizerTripAsync du composant C++ se comporte de manière asynchrone. Par conséquent, la partie JavaScript de l'application doit pouvoir traiter les données lorsqu'elles deviennent disponibles. La partie JavaScript utilise des promesses pour réagir lorsqu'une opération asynchrone se termine, lève une erreur ou signale une progression. L'exemple suivant montre comment la fonction optimizerOptimizeTrip définit les rappels d'achèvement, d'erreur et de progression pour l'appel de 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);
                }
            }
            asyncOperation = null;
        },
        function (error) {
            if (error.description === "Canceled") {
                canceledCallback();
            }
            else {
                errorCallback("Error: " + error.message);
            }
            asyncOperation = null;
        },
        function (progress) {
            progressCallback(progress);
        }
        );
}

Notez que lorsque l'utilisateur choisit Cancel, le composant C++ annule l'opération en cours. Le runtime appelle le gestionnaire d'erreurs pour l'opération. Il définit le champ description de l'erreur sur « Canceled » pour indiquer que le résultat doit être annulé. Pour plus d'informations sur l'utilisation des opérations asynchrones dans JavaScript, consultez Asynchronous programming.

Lorsque le contexte local reçoit la progression ou le résultat d'une opération asynchrone, il transmet les données d'événement au contexte Web pour que celui-ci mette à jour l'interface utilisateur. Par exemple, la fonction progressCallback envoie la chaîne « progressCallback » dans le cadre du message qu'elle envoie au contexte Web.

// 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), "*");
}

L'exemple suivant montre la fonction receiveMessage pour le contexte Web. Cette fonction reçoit des messages du contexte local.

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

Pour le message « progressCallback », le contexte Web appelle la fonction progressCallback, qui met à jour l'interface utilisateur pour afficher le message de progression.

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

[Haut]

Migration à partir d'ActiveX

Pour plus d'informations sur la migration de la version ActiveX de l'optimiseur de voyage Bing Maps vers une application Windows Store, consultez Migration du code existant dans l'exemple de l'optimiseur de voyage Bing Maps.

[Haut]

Étapes suivantes

Cet article a expliqué comment nous avons utilisé JavaScript et C++ pour créer une application Windows Store complète. Pensez à utiliser un composant c++ avec votre application JavaScript pour tirer parti du code que vous avez déjà écrit et testé et améliorer les performances.

[Haut]