Migration du code existant dans l'exemple de l'optimiseur de voyage Bing Maps
Ce document met en évidence certaines des recommandations principales que nous avons suivies lorsque nous avons migré de la version ActiveX de l'optimiseur de voyage Bing Maps à une application Windows Store. Ce document ne fournit pas d'explication complète à propos de la migration du code existant vers Windows Runtime. Au contraire, il met en surbrillance notre expérience et les aspects importants dont nous avons eu à tenir compte.
Notes
L'exemple de code qui correspond à ce document se trouve dans Exemple d'optimiseur de voyage Bing Maps (application Windows Store) et Optimiseur de voyage Bing Maps (application Web ActiveX).
Dans cet article
Points clés de la migration JavaScript
Points clés de la migration C++
Points clés de la migration de l'interopérabilité
Points clés de la migration JavaScript
La version ActiveX de l'optimiseur de voyage Bing Maps utilise un fichier de code, OptimizerControl.htm, pour l'interface utilisateur. Comme décrit dans cette documentation, lorsque nous avons migré pour utiliser Windows Runtime, nous avons du établir des contextes distincts pour les composants qui interagissent avec le Web et ceux qui interagissent avec Windows Runtime. Nous avons eu à écrire du code supplémentaire pour permettre aux contextes de communiquer. Le document Features and restrictions by context explique en détail les différences entre les variables locales et les contextes de site Web.
Nous avons pu utiliser la plupart du code de la version d'origine dans la version d'application de Windows Store. Une différence principale réside dans le fait que l'application de Windows Store ne fait plus référence à un contrôle ActiveX, nous avons remplacé l'élément object par une variable globale qui représente le composant C++. Ce mécanisme est expliqué en détail dans Interopérabilité entre JavaScript et C++ dans l'exemple de l'optimiseur de voyage Bing Maps.
Les méthodes de fenêtre comme alert, prompt et open ne fonctionnent pas dans les applications Windows Store JavaScript. La version ActiveX du contrôle utilise alert pour signaler un problème à l'utilisateur, par exemple lorsque plus de 25 emplacements ont été entrés. La version Windows Store de l'application utilise la classe Windows.UI.Popups.MessageDialog pour afficher des messages à l'utilisateur.
// Show message dialog.
new Windows.UI.Popups.MessageDialog(data.message).showAsync().then();
Étant donné qu'il n'y a aucune action à exécuter une fois la boîte de dialogue de message affichée, l'instruction then est vide. Pour plus d'informations sur l'utilisation des opérations asynchrones dans JavaScript, consultez Asynchronous programming.
Pour plus d'informations sur certaines des différences dans la façon dont vous utilisez des fonctionnalités HTML existantes dans une application Windows Store JavaScript, consultez HTML, CSS, and JavaScript features and differences.
La version ActiveX de l'application utilise la version 6.3 du contrôle AJAX Bing Maps pour afficher la carte sur l'interface utilisateur. La version d'application de Windows Store utilise la version 7.0 du contrôle AJAX Bing Maps. La mise à niveau de la version 6.3 vers la version 7.0 n'est pas obligatoire. Vous pouvez utiliser la version 6.3 dans une application de Windows Store. Nous avons sélectionné la version 7.0 dans cette implémentation car elle inclut des améliorations en termes de performances et une prise en charge améliorée pour les fonctions tactiles, et nous avons souhaité illustrer la façon la plus récente d'obtenir les informations de Bing Maps.
[Haut]
Points clés de la migration C++
Lorsque vous utilisez C++/CX pour créer des composants Windows Store, le compilateur et Windows Runtime gèrent l'infrastructure requise pour interagir avec d'autres composants et langages. Lorsque nous avons migré la version ActiveX du contrôle vers un composant Windows Store, nous avons pu supprimer le code d'infrastructure requis pour implémenter une interface COM personnalisée. Par exemple, un composant Windows Runtime ne requiert pas de fichiers IDL qui définissent les interfaces et les événements qu'un composant fournit. En outre, nous avons conservé les détails d'implémentation qui utilisent le code natif pur lorsque nous le pouvions. L'utilisation de C++/CX et de Windows Runtime est obligatoire uniquement lorsque le contrôle interagit avec d'autres objets et composants Windows Runtime.
Tenez compte de ces indications que vous migrez vos contrôles ActiveX vers des contrôles qui utilisent Windows Runtime.
Conseil
Plusieurs de ces indications impliquent l'utilisation de la syntaxe C++/CX. Pour plus d'informations sur cette syntaxe, consultez Référence du langage Visual C++ (C++/CX).
Utilisez le modèle de Bibliothèque de classes WinRT pour créer le projet Visual Studio.
Ajoutez les méthodes d'interface publique et les propriétés du contrôle ActiveX à votre classe Windows Runtime. Convertissez le paramètre et les types de retour pour utiliser les types compatibles avec Windows Runtime. Par exemple, TripOptimizerImpl.idl définit l'interface IOptimizerControl du contrôle ActiveX.
interface IOptimizerControl : IDispatch{ [id(1)] HRESULT OptimizeTripAsync([in] VARIANT* waypoints, [in] BSTR travelMode, [in] BSTR optmz, [in] BSTR bingMapsKey, [in] DOUBLE alpha, [in] DOUBLE beta, [in] DOUBLE rho, [in] ULONG iterations, [in] VARIANT_BOOL parallel); [id(2)] HRESULT CancelAsync(); };
Pour le composant Windows Store, voici la déclaration de la méthode TripOptimizer::OptimizeTripAsync dans le composant Windows Runtime. Nous utilisons le type de retour réel Windows::Foundation::Collections::IMap<K, V>, au lieu de HRESULT. Nous utilisons également le type Windows Runtime approprié pour chaque paramètre.
Notes
Nous avons pu supprimer la méthode CancelAsync dans cette implémentation car la fonctionnalité d'annulation est fournie par la méthode ::Cancel De Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress>.
// Optimizes a trip as an asynchronous process. Windows::Foundation::IAsyncOperationWithProgress< Windows::Foundation::Collections::IMap< Platform::String^, Windows::Foundation::Collections::IVector<Platform::String^>^>^, Platform::String^>^ OptimizeTripAsync( Windows::Foundation::Collections::IVector<Platform::String^>^ waypoints, Platform::String^ travelMode, Platform::String^ optimize, Platform::String^ bingMapsKey, double alpha, double beta, double rho, unsigned int iterations, bool parallel);
La méthode TripOptimizer::OptimizeTripAsync est expliquée plus en détail dans la section Création de classes TripOptimizer et TripOptimizerImpl.
Ajoutez les événements publics du contrôle ActiveX à votre classe Windows Runtime. Comme avec des méthodes et des propriétés, vous devez convertir le paramètre et les types de retour pour utiliser les types compatibles avec Windows Runtime.
Dans cette implémentation, nous avons pu supprimer tous les événements définis dans la version ActiveX car ces actions sont toutes gérées par d'autres moyens. Par exemple, nous n'avons plus à définir un événement d'achèvement car nous renvoyons le résultat directement dans le cadre de l'objet IAsyncOperationWithProgress<TResult, TProgress> retourné par TripOptimizer::OptimizeRouteAsync. Les rappels d'erreur et de progression sont également gérés par l'objet IAsyncOperationWithProgress<TResult, TProgress>. Pour plus d'informations sur la façon dont la partie JavaScript de l'application utilise l'opération asynchrone, consultez Interopérabilité entre JavaScript et C++ dans l'exemple de l'optimiseur de voyage Bing Maps.
Sélectionnez le standard C++ et les types Windows Runtime appropriés lorsque vous définissez des données membres pour votre classe Windows Runtime.
Par exemple, la classe COptimizerControl utilise des types COM tels que _bstr_t pour stocker des valeurs de chaîne.
Dans la version Windows Store de l'application, nous avons utilisé std::wstring, le type de chaîne C++ standard, pour contenir des valeurs de chaîne. Par exemple, dans la méthode TripOptimizerImpl::OptimizeTripAsync, nous convertissons les paramètres Windows::Foundation::Collections::IVector<T> et Platform::String à std::vector et std::wstring, car ces variables ne sont pas passées à un composant Windows Runtime.
// Copy inputs to a OptimizeTripParams structure. auto params = make_shared<OptimizeTripParams>(); for (auto waypoint : waypoints) { params->Waypoints.push_back(waypoint->Data()); } params->TravelMode = wstring(travelMode->Data()); params->Optimize = wstring(optimize->Data()); params->BingMapsKey = UriEncode(bingMapsKey->Data()); params->Alpha = alpha; params->Beta = beta; params->Rho = rho; params->Iterations = iterations; params->Parallel = parallel;
Lorsque vous utilisez cette convention, vous pouvez plus clairement distinguer les variables qui sont utilisées avec Windows Runtime. La chaîne et les types de collection Windows Runtime (comme Windows::Foundation::Collections::IMap<K, V> et Windows::Foundation::Collections::IVector<T>) sont utiles lorsque vous communiquez régulièrement entre Windows Runtime et votre code parce qu'il réduit le nombre de conversions de type chaîne que l'application doit effectuer. Vous devez, sinon, envisager d'utiliser des types de collection C++ standard tels que std::map et std::vector.
Les détails de l'implémentation du contrôle sont décrits plus en détail dans la section Flux de travail du composant.
Utilisez les interfaces Windows::Foundation::IAsyncActionWindows::Foundation::IAsyncActionWithProgress<TProgress>Windows::Foundation::IAsyncOperation<TResult>, ou Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress> pour définir des méthodes asynchrones. La fonction concurrency::create_async est la méthode recommandée pour créer ces objets à partir d'une application ou d'un composant Windows Store C++.
Utilisez le code existant autant que possible. Nous avons pu migrer les détails d'implémentation, tels que l'algorithme d'optimisation de colonies de fourmis, avec peu ou pas de modifications de code. Toutefois, comme les applications Windows Store peuvent utiliser un sous-ensemble d'API Win32 et COM, nous avons dû utiliser d'autres mécanismes pour certaines parties du composant. Par exemple, la version ActiveX du contrôle utilise IXMLHTTPRequest pour communiquer avec les serveurs HTTP. Dans le composant C++, nous utilisons IXMLHTTPRequest2, qui est la méthode recommandée pour communiquer avec les serveurs HTTP dans une application Windows Store. Pour traiter la réponse XML à partir de Bing Maps, le contrôle ActiveX utilise XmlLite. Dans le composant Windows Store, nous utilisons la classe Windows Runtime XmlDocument car elle est facile à utiliser et nous avons souhaité montrer comment vous pouvez mettre à jour le code COM existant pour utiliser les types Windows Runtime. Toutefois, si vous avez un code Win32 ou COM existant qui est disponible dans une application Windows Store, vous pouvez continuer à l'utiliser.
Pour plus d'informations sur la façon d'utiliser Win32 et COM dans une application Windows Store, consultez l'article sur Win32 et COM pour les applications Windows Store.
Important
Si vous utilisez Win32 et COM dans votre application Windows Store, elle fonctionne dans votre environnement de développement, mais elle peut ne pas être approuvée pour la distribution de Windows Store. Par conséquent, il est recommandé d'exécuter le vérificateur d'application fréquemment pour vous assurer que votre application passe la vérification. Pour plus d'informations, consultez Préparation de votre application pour le magasin d'applications Windows et Comment : Installer, valider et télécharger votre package.
Les projets Visual C++ utilisent désormais pch.h et pch.cpp pour stocker les informations d'en-tête précompilé. Migrer les instructions #include appropriées de stdafx.h à pch.h.
[Haut]
Points clés de la migration de l'interopérabilité
Dans la version d'application de Windows Store de l'optimiseur de voyage Bing Maps, nous avons pu utiliser la majeure partie du code JavaScript de la version ActiveX. La principale différence réside dans la façon dont le code HTML et JavaScript référencent le composant C++.
La version ActiveX utilise la balise object HTML pour référencer le composant C++.
<object id="OptimizerControl" name="OptimizerControl" classid="CLSID:10FFAAB9-0E73-4C4D-8118-6225C7F2E692"></object>
Par conséquent, la version ActiveX utilise la valeur id, « OptimizerControl », pour appeler les méthodes COptimizerControl.
La version d'application de Windows Store de l'optimiseur de voyage Bing Maps définit une référence de projet et utilise une variable globale au lieu d'utiliser la balise object. Le système de projet exécute les étapes requises pour que l'application JavaScript recherche et charge le composant C++. L'article Création de composants Windows Runtime en C++ explique en détail comment définir les références d'un projet.
La version ActiveX utilise la syntaxe :: pour gérer des événements.
// Event handler for progress notifications from the control.
function document.OptimizerControl::ProgressCallback(message) {
// Set message.
ProgressMessageText.innerHTML = message;
}
La version d'application de Windows Store utilise le traitement asynchrone et promet de réagir aux réponses du composant C++. Ce processus est illustré dans la section Réception de données depuis le composant C++.
[Haut]