Condividi tramite


Migrazione del codice esistente nell'esempio di 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 si trova nell'esempio di utilità di ottimizzazione dei viaggi di Bing Mappe (app Windows Store) e Utilità di ottimizzazione dei viaggi di Bing Mappe (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'esempio di 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 di 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 Windows Store usa 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. Verrà utilizzato il tipo restituito, 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'esempio di 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 poiché queste variabili non vengono passate nuovamente a un componente 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 (ad esempio Windows::Foundation::Collections::IMap<K, V> e Windows::Foundation::Collections::IVector<T>) sono utili quando si comunica regolarmente tra Windows Runtime e il codice, poiché riducono il numero delle conversioni dei tipi 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 le interfacce Windows::Foundation::IAsyncAction, Windows::Foundation::IAsyncActionWithProgress<TProgress>, Windows::Foundation::IAsyncOperation<TResult> o Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress> per agevolare la definizione dei 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 Mappe, il controllo ActiveX utilizza XmlLite. Nel componente Windows Store utilizziamo la classe Windows Runtime XmlDocument perché è facile da utilizzare e ci permette di illustrare come è possibile aggiornare il codice COM esistente per utilizzare i tipi Windows Runtime. Tuttavia, se disponi di codice Win32 o COM esistente in un'app di Windows Store, puoi continuare a utilizzarlo.

    Per ulteriori informazioni sull'utilizzo di Win32 e COM in un'app Windows Store, vedi Win32 e COM per le app 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 Invio dell'app e Procedura: 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 dei dati dal componente C++.

[All'inizio]