Migrazione del codice esistente nell'utilità di ottimizzazione dei viaggi di Bing Mappe
Il documento illustra alcune linee guida fondamentali che abbiamo adottato per la migrazione dalla versione ActiveX dell'utilità di ottimizzazione dei viaggi di Bing Maps a un'app di Windows Store. Non viene fornita una spiegazione completa di come eseguire la migrazione del codice esistente a Windows Runtime. Viene invece illustrata la nostra esperienza e gli aspetti importanti che abbiamo tenuto in considerazione.
Nota
Il codice di esempio che corrisponde a questo documento è disponibile nell'esempio dell'utilità di ottimizzazione dei viaggi di Bing Maps (Windows Store) e nella pagina relativa all'utilità di ottimizzazione dei viaggi di Bing Maps (app Web ActiveX).
In questo articolo
Punti chiave della migrazione JavaScript
Punti chiave della migrazione C++
Punti chiave della migrazione Interop
Punti chiave della migrazione JavaScript
La versione ActiveX dell'utilità di ottimizzazione dei viaggi di Bing Mappe utilizza un file di codice, OptimizerControl.htm, per l'interfaccia utente. Come descritto in questa documentazione, quando abbiamo eseguito la migrazione per utilizzare Windows Runtime, abbiamo dovuto creare contesti separati per i componenti che interagiscono con il Web e per quelli che interagiscono con Windows Runtime. Abbiamo scritto codice aggiuntivo per consentire la comunicazione tra i contesti. Nel documento Features and restrictions by context vengono illustrate in modo più dettagliato le differenze tra il contesto locale e quello Web.
Abbiamo potuto utilizzare la maggior parte del codice dalla versione originale nella versione dell'app in Windows Store. Una differenza fondamentale è data dal fatto che l'app in Windows Store non fa più riferimento a un controllo ActiveX, pertanto abbiamo sostituito l'elemento object con una variabile globale che rappresenta il componente C++. Questo meccanismo è illustrato più dettagliatamente in Interazione tra JavaScript e C++ nell'utilità di ottimizzazione dei viaggi di Bing Mappe.
I metodi Windows come alert, prompt e open non funzionano nelle app di Windows Store JavaScript. La versione ActiveX del controllo utilizza alert per informare l'utente di un problema, ad esempio quando sono state immesse più di 25 località. La versione Windows Store dell'app utilizza la classe Windows.UI.Popups.MessageDialog per visualizzare i messaggi all'utente.
// Show message dialog.
new Windows.UI.Popups.MessageDialog(data.message).showAsync().then();
Poiché non vi sono azioni da eseguire dopo la visualizzazione della finestra di messaggio, l'istruzione then è vuota. Per ulteriori informazioni su come utilizzare le operazioni asincrone in JavaScript, vedi Asynchronous programming.
Per ulteriori informazioni su alcune differenze relative alla modalità di utilizzo delle funzionalità HTML esistenti in un'app di Windows Store JavaScript, vedi HTML, CSS, and JavaScript features and differences.
La versione ActiveX dell'app utilizza il controllo AJAX di Bing Mappe versione 6.3 per visualizzare la mappa nell'interfaccia utente. La versione dell'app in stile Windows Store utilizza il controllo AJAX di Bing Mappe versione 7.0. L'aggiornamento dalla versione 6.3 alla versione 7.0 non era un requisito; puoi utilizzare la versione 6.3 in un'app in Windows Store. Abbiamo scelto la versione 7.0 in questa implementazione perché include miglioramenti delle prestazioni e il supporto migliorato per il tocco e desideravamo illustrare la modalità più nuova di ottenere informazioni da Bing Mappe.
[All'inizio]
Punti chiave della migrazione C++
Quando utilizzi C++/CX per creare componenti di Windows Store, il compilatore e Windows Runtime gestiscono l'infrastruttura necessaria per interagire con altri componenti e linguaggi. Quando abbiamo eseguito la migrazione della versione ActiveX del controllo a un componente di Windows Store, abbiamo potuto rimuovere il codice di infrastruttura richiesto per implementare un'interfaccia COM personalizzata. Ad esempio, un componente di Windows Runtime non richiede file IDL che definiscono le interfacce e gli eventi forniti da un componente. Inoltre, quando possibile abbiamo mantenuto i dettagli dell'implementazione che utilizzano codice nativo puro. L'utilizzo di C++/CX e di Windows Runtime è obbligatorio solo quando il controllo interagisce con altri oggetti e componenti di Windows Runtime.
Considera queste linee guida per eseguire la migrazione di controlli ActiveX ai controlli che utilizzano Windows Runtime.
Suggerimento
Molte di queste linee guida prevedono l'utilizzo della sintassi di C++/CX. Per ulteriori informazioni su questa sintassi, vediRiferimenti al linguaggio Visual C++ (C++/CX).
Utilizza il modello Libreria di classi WinRT per creare il progetto di Visual Studio.
Aggiungi i metodi e le proprietà dell'interfaccia pubblica dal controllo ActiveX nella classe di Windows Runtime. Converti il parametro e i tipi restituiti per utilizzare i tipi compatibili con Windows Runtime. Ad esempio, TripOptimizerImpl.idl definisce l'interfaccia di IOptimizerControl per il controllo 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(); };
Per il componente di Windows Store, ecco la dichiarazione per il metodo TripOptimizer::OptimizeTripAsync nel componente di Windows Runtime. Utilizziamo il tipo restituito effettivo, Windows::Foundation::Collections::IMap<K, V>, anziché HRESULT. Utilizziamo inoltre il tipo di Windows Runtime appropriato per ogni parametro.
Nota
Abbiamo potuto rimuovere il metodo CancelAsync in questa implementazione perché la funzionalità di annullamento viene fornita dal metodo Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress>::Cancel.
// 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);
Il metodo TripOptimizer::OptimizeTripAsync è illustrato più dettagliatamente nella sezione Creazione delle classi TripOptimizer e TripOptimizerImpl.
Aggiungi gli eventi pubblici dal controllo ActiveX nella classe di Windows Runtime. Come per i metodi e le proprietà, converti il parametro e i tipi restituiti per utilizzare i tipi compatibili con Windows Runtime.
In questa implementazione, abbiamo potuto rimuovere tutti gli eventi definiti nella versione ActiveX perché tutte queste azioni sono gestite in altri modi. Ad esempio, non è più necessario che definiamo un evento di completamento poiché restituiamo il risultato direttamente come parte dell'oggetto IAsyncOperationWithProgress<TResult, TProgress> restituito da TripOptimizer::OptimizeRouteAsync. I callback di errore e di stato vengono anche gestiti dall'oggetto IAsyncOperationWithProgress<TResult, TProgress>. Per ulteriori informazioni sulla modalità di utilizzo dell'operazione asincrona della parte JavaScript dell'app, vedi Interazione tra JavaScript e C++ nell'utilità di ottimizzazione dei viaggi di Bing Mappe.
Scegli i tipi di Windows Runtime e C++ standard quando definisci i membri dati per la classe di Windows Runtime.
Ad esempio, la classe COptimizerControl utilizza tipi COM come _bstr_t per contenere i valori stringa.
Nella versione di Windows Store dell'app, abbiamo utilizzato std::wstring, il tipo di stringa C++ standard, per contenere i valori stringa. Ad esempio nel metodo TripOptimizerImpl::OptimizeTripAsync convertiamo i parametri Windows::Foundation::Collections::IVector<T> e Platform::String in std::vector e std::wstring perché queste variabili non vengono ripassate a un componente di 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;
Quando utilizzi questa convenzione, puoi distinguere più facilmente quali variabili vengono utilizzate da Windows Runtime. I tipi di stringa e raccolta di Windows Runtime quali Windows::Foundation::Collections::IMap<K, V> e Windows::Foundation::Collections::IVector<T> sono utili per comunicare regolarmente tra Windows Runtime e il codice perché riduce il numero di conversioni del tipo di stringa che l'app deve eseguire. In alternativa, valuta se utilizzare i tipi di raccolta C++ standard, ad esempio std::map e std::vector.
I dettagli relativi all'implementazione del controllo sono descritti in modo più approfondito nella sezione Flusso di lavoro del componente.
Utilizza l'interfaccia Windows::Foundation::IAsyncAction, Windows::Foundation::IAsyncActionWithProgress<TProgress>, Windows::Foundation::IAsyncOperation<TResult>, or Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress> per agevolare la definizione di metodi asincroni. La funzione concurrency::create_async è il modo consigliato per creare questi oggetti da un'app o un componente di Windows Store C++.
Utilizza il più possibile il codice esistente. Abbiamo potuto migrare i dettagli di implementazione, ad esempio l'algoritmo di ottimizzazione ACO, senza modificare il codice o apportando pochi cambiamenti. Poiché le app di Windows Store possono utilizzare un subset delle API Win32 e COM, tuttavia, abbiamo dovuto utilizzare meccanismi alternativi per alcune parti del componente. Ad esempio, la versione ActiveX del controllo utilizza IXMLHTTPRequest per comunicare con i server HTTP. Nel componente C++, utilizziamo IXMLHTTPRequest2, che è il modo consigliato per comunicare con i server HTTP in un'app di Windows Store. Per elaborare la risposta XML da Bing Maps, il controllo ActiveX utilizza XmlLite. Nel componente di Windows Store, utilizziamo la classe XmlDocument di Windows Runtime perché è di facile utilizzo e ci permette di illustrare come è possibile aggiornare il codice COM esistente per utilizzare i tipi di Windows Runtime. Tuttavia, se disponi di codice Win32 o COM esistente in un'app di Windows Store, puoi continuare a utilizzarlo.
Per ulteriori informazioni su come utilizzare Win32 e COM in un'app di Windows Store, vedi l'articolo relativo a Win32 e COM per le applicazioni di Windows Store.
Importante
Se utilizzi Win32 e COM nell'app di Windows Store, è possibile che venga eseguito nell'ambiente di sviluppo, ma che non sia approvato per la distribuzione da Windows Store. Di conseguenza, ti consigliamo di eseguire spesso lo strumento Application Verifier per garantire che l'app passi la verifica. Per ulteriori informazioni, vedi l'articolo relativo allapreparazione dell'app per Windows Store e quello relativo a come installare, convalidare e caricare il pacchetto.
I progetti di Visual C++ ora utilizzano pch.h e pch.cpp per contenere le informazioni di intestazione precompilate. Eseguire la migrazione delle #include rilevanti da stdafx.h a pch.h.
[All'inizio]
Punti chiave della migrazione Interop
Nella versione dell'app in Windows Store dell'utilità di ottimizzazione dei viaggi di Bing Mappe abbiamo potuto utilizzare la maggior parte del codice JavaScript dalla versione ActiveX. La differenza principale è la modalità in cui il codice JavaScript e HTML fa riferimento al componente C++.
La versione ActiveX utilizza il tag HTML object per fare riferimento al componente C++.
<object id="OptimizerControl" name="OptimizerControl" classid="CLSID:10FFAAB9-0E73-4C4D-8118-6225C7F2E692"></object>
Di conseguenza, la versione ActiveX utilizza il valore id, "OptimizerControl", per chiamare i metodi COptimizerControl.
La versione dell'app in Windows Store dell'utilità di ottimizzazione dei viaggi di Bing Mappe imposta un riferimento al progetto e utilizza una variabile globale anziché il tag object. Il sistema del progetto esegue i passaggi necessari per l'app JavaScript per individuare e caricare il componente C++. Nell'articolo Creazione di componenti Windows Runtime in C++ viene illustrato in dettaglio come impostare i riferimenti al progetto.
La versione ActiveX utilizza la sintassi :: per gestire gli eventi.
// Event handler for progress notifications from the control.
function document.OptimizerControl::ProgressCallback(message) {
// Set message.
ProgressMessageText.innerHTML = message;
}
La versione dell'app in Windows Store utilizza l'elaborazione asincrona e dovrà reagire alle risposte ricevuto dal componente C++. Questo processo viene illustrato nella sezione Ricezione di dati dal componente C++.
[All'inizio]