Freigeben über


Migrieren von vorhandenem Code im Beispiel zum Reise-Optimierer von Bing Maps

In diesem Dokument werden einige der wichtigsten Richtlinien vorgestellt, die bei der Migration der ActiveX-Version des Reise-Optimierer von Bing Maps zu einer Windows Store-App beachtet wurden. Es wird nicht ausführlich beschrieben, wie vorhandener Code zu Windows-Runtime migriert werden kann. Stattdessen werden unsere Erfahrungen und die wichtigsten Aspekte beschrieben.

Hinweis

Der Beispielcode, auf den sich diese Unterlagen beziehen, kann auf der Seite mit dem Codebeispiel für den Reise-Optimierer von Bing Maps (Windows Store-App) und auf der Seite für den Reise-Optimierer von Bing Maps (ActiveX-Webanwendung) eingesehen werden.

In diesem Artikel

  • Wichtige Punkte der JavaScript-Migration

  • Wichtige Punkte der C++-Migration

  • Wichtige Punkte der Interop-Migration

Wichtige Punkte der JavaScript-Migration

Die ActiveX-Version des Reise-Optimierers von Bing Maps verwendet eine Codedatei für die Benutzeroberfläche: OptimizerControl.htm. In diesen Unterlagen wird erläutert, dass wir bei der Migration zur Windows-Runtime-Benutzung separate Kontexte für Komponenten, die mit dem Internet interagieren, und solche, die mit Windows-Runtime interagieren, einrichten mussten. Es musste zusätzlicher Code geschrieben werden, damit die Kontexte miteinander kommunizieren können. Weitere Informationen zu den Unterschieden zwischen lokalen Kontexten und Internetkontexten finden Sie hier: Features and restrictions by context.

Wir konnten den Großteil des Codes der ursprünglichen Version in der Windows Store-App-Version verwenden. Die Windows Store-App verweist nicht mehr auf ein ActiveX-Steuerelement, sodass wir das object-Element durch eine globale Variable ersetzt haben, die die C++-Komponente darstellt. Dieser Mechanismus wird ausführlich in Zusammenwirken von JavaScript und C++ im Beispiel zum Reise-Optimierer von Bing Maps erläutert.

Windows-Methoden wie alert, prompt und open funktionieren nicht in JavaScript-Windows Store-Apps. Die ActiveX-Version des Steuerelements verwendet alert, um den Benutzer über ein Problem zu informieren; beispielsweise bei der Eingabe von mehr als 25 Positionen. Die Windows Store-Version der App verwendet die Windows.UI.Popups.MessageDialog-Klasse, um Nachrichten für den Benutzer anzuzeigen.

// Show message dialog.            
new Windows.UI.Popups.MessageDialog(data.message).showAsync().then();

Da nach der Anzeige des Nachrichtendialogfelds keine Aktion ausgeführt werden muss, ist die then-Anweisung leer. Weitere Informationen zum Umgang mit asynchronen Vorgängen in JavaScript finden Sie unter Asynchronous programming.

Weitere Informationen zur Verwendung vorhandener HTML-Funktionen in einer JavaScript-Windows Store-App finden Sie unter HTML, CSS, and JavaScript features and differences.

Die ActiveX-Version der App verwendet das AJAX-Steuerelement für Bing Maps, Version 6.3, um die Zuordnung auf der Benutzeroberfläche anzuzeigen. Die Windows Store-App-Version verwendet das AJAX-Steuerelement für Bing Maps, Version 7.0. Die Aktualisierung von Version 6.3 auf Version 7.0 war nicht zwingend erforderlich. Sie können Version 6.3 in einer Windows Store-App verwenden. Wir haben uns in dieser Implementierung für die Version 7.0 entschieden, da sie Leistungsverbesserungen und verbesserte Unterstützung für die Fingereingabe umfasst. Außerdem wollten wir die neueste Methode für den Informationsabruf in Bing Maps veranschaulichen.

[Nach oben]

Wichtige Punkte der C++-Migration

Wenn Sie C++/CX verwenden, um Windows Store-Komponenten zu erstellen, sind Compiler und Windows-Runtime für die Infrastruktur verantwortlich, die für die Kompatibilität mit anderen Komponenten und Sprachen erforderlich ist. Während der Migration der ActiveX-Version des Steuerelements zu einer Windows Store-Komponente haben wir den Infrastrukturcode entfernt, der für die Implementierung einer benutzerdefinierten COM-Schnittstelle erforderlich ist. Beispielsweise erfordert eine Windows-Runtime-Komponente keine IDL-Dateien, die die Schnittstellen und Ereignisse einer Komponente definieren. Außerdem wurden die Implementierungsdetails, die reinen systemeigenen Code verwenden, wo möglich beibehalten. Die Verwendung von C++/CX und Windows-Runtime ist nur erforderlich, wenn das Steuerelement mit anderen Windows-Runtime-Objekten und -Komponenten interagiert.

Beachten Sie bitte diese Richtlinien bei der Migration Ihrer ActiveX-Steuerelemente zu Steuerelementen, die Windows-Runtime verwenden.

Tipp

Viele dieser Richtlinien beziehen sich auf die C++-/CX-Syntax. Weitere Informationen zu dieser Syntax finden Sie unter Sprachreferenz zu Visual C++ (C++/CX).

  • Verwenden Sie für die Erstellung des Visual Studio-Projekts die WinRT-Klassenbibliotheksvorlage.

  • Fügen Sie die Methoden und Eigenschaften der öffentlichen Schnittstelle aus dem ActiveX-Steuerelement zur Windows-Runtime-Klasse hinzu. Konvertieren Sie den Parameter und die Rückgabetypen, um Typen zu verwenden, die mit Windows-Runtime kompatibel sind. Beispielsweise definiert die TripOptimizerImpl.idl die IOptimizerControl-Schnittstelle für das ActiveX-Steuerelement.

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

    Für die Windows Store-Komponente ist dies die Deklaration für die TripOptimizer::OptimizeTripAsync-Methode in der Windows-Runtime-Komponente. Wir verwenden den tatsächlichen Rückgabetyp Windows::Foundation::Collections::IMap<K, V> anstatt HRESULT. Außerdem verwenden den entsprechenden Windows-Runtime-Typ für jeden Parameter.

    Hinweis

    Wir konnten die CancelAsync-Methode in dieser Implementierung entfernen, da die Abbruchfunktionalität von der Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress>::Cancel-Methode bereitgestellt wird.

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

    Weitere Informationen zur TripOptimizer::OptimizeTripAsync-Methode finden Sie im Abschnitt Erstellen der TripOptimizer und TripOptimizerImpl-Klassen.

  • Fügen Sie die öffentlichen Ereignisse vom ActiveX-Steuerelement zur Windows-Runtime-Klasse hinzu. Wie bei den Methoden und Eigenschaften müssen Sie für die Verwendung von Typen, die mit Windows-Runtime kompatibel sind, die Parameter- und Rückgabetypen konvertieren.

    In dieser Implementierung konnten wir alle Ereignisse entfernen, die in der ActiveX-Version definiert wurden, da diese Aktionen alle auf andere Weise behandelt werden. Beispielsweise müssen wir ein Abschlussereignis nicht mehr definieren, da wir das Ergebnis direkt als Teil des IAsyncOperationWithProgress<TResult, TProgress>-Objekts zurückgeben, das von TripOptimizer::OptimizeRouteAsync zurückgegeben wird. Das IAsyncOperationWithProgress<TResult, TProgress>-Objekt übernimmt außerdem die Fehler- und Statusrückrufe. Weitere Informationen zur Nutzung der asynchronen Operation durch den JavaScript-Teil der App finden Sie unter Zusammenwirken von JavaScript und C++ im Beispiel zum Reise-Optimierer von Bing Maps.

  • Wählen Sie für die Definition der Datenmember für die Windows-Runtime-Klasse die entsprechenden Standard C++- und Windows-Runtime-Typen aus.

    Beispielsweise verwendet die COptimizerControl-Klasse COM-Typen wie _bstr_t, um Zeichenfolgenwerte aufzunehmen.

    In der Windows Store-Version der App verwenden wir std::wstring, den Standard-C++-Zeichenfolgentyp, um Zeichenfolgenwerte aufzunehmen. In der TripOptimizerImpl::OptimizeTripAsync-Methode wurden die Parameter Windows::Foundation::Collections::IVector<T> und Platform::String zu std::vector und std::wstring konvertiert, da diese Variablen nicht an die Windows-Runtime-Komponente zurückgegeben werden.

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

    Bei Verwendung dieser Konvention lässt sich eindeutig unterscheiden, welche Variablen mit Windows-Runtime verwendet werden. Die Windows-Runtime-Zeichenfolgen und -Auflistungstypen (wie Windows::Foundation::Collections::IMap<K, V> und Windows::Foundation::Collections::IVector<T>) sind nützlich, wenn regelmäßig zwischen Windows-Runtime und dem Code kommuniziert wird. Denn die Anzahl von Zeichenfolgentypkonvertierungen, die die Anwendung ausführen muss, wird reduziert. Andernfalls sollten Sie die Verwendung von Standard-C++-Auflistungstypen wie std::map und std::vector in Erwägung ziehen.

    Weitere Informationen zur Implementierung des Steuerelements finden Sie im Abschnitt Komponenten-Workflow beschrieben.

  • Die folgenden Schnittstellen helfen bei der Definition asynchroner Methoden: Windows::Foundation::IAsyncAction Sie Windows::Foundation::IAsyncActionWithProgress<TProgress>, Windows::Foundation::IAsyncOperation<TResult> oder Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress>. Die concurrency::create_async-Funktion wird für das Erstellen dieser Objekte aus einer C++-Windows Store-App oder -Komponente empfohlen.

  • Verwenden Sie so viel vorhandenen Code wie möglich. Für die Migration von Implementierungsdetails wie dem Ameisenkolonien-Optimierungsalgorithmus waren nur wenige oder gar keine Codeänderungen erforderlich. Da Windows Store-Apps eine Teilmenge der Win32- und COM-API verwenden, mussten wir allerdings für einige Teile der Komponente alternative Mechanismen verwenden. Beispielsweise verwendet die ActiveX-Version des Steuerelements IXMLHTTPRequest für die Kommunikation mit HTTP-Servern. In der C++-Komponente verwenden wir IXMLHTTPRequest2. Dies ist die empfohlene Methode für die Kommunikation mit HTTP-Servern in einer Windows Store-App. Für die Verarbeitung der XML-Antwort von Bing Maps nutzt das ActiveX-Steuerelement XmlLite. In der Windows Store-Komponente verwenden wir die Windows-Runtime XmlDocument-Klasse, da sie einfach zu verarbeiten ist und wir veranschaulichen wollten, wie Sie vorhandenen COM-Code für die Verwendung der Windows-Runtime-Typen aktualisieren können. Sie können auch weiterhin vorhandenen Win32- oder COM-Code nutzen, der in einer Windows Store-App verfügbar ist.

    Weitere Informationen zur Verwendung von Win32 und COM in einer Windows Store-App finden Sie unter Win32 und COM für Windows Store-Apps.

    Wichtig

    Wenn Sie Win32 und COM in der Windows Store-App verwenden, kann die Anwendung in der Entwicklungsumgebung ausgeführt werden, aber sie wird eventuell von Windows Store nicht für die Verteilung zugelassen. Daher empfehlen wir die regelmäßige Ausführung des Application Verifiers, um die erfolgreiche Überprüfung der App sicherzustellen. Weitere Informationen finden Sie unter Vorbereiten Ihrer App auf den Windows Store und auf der Seite mit Informationen zum Installieren, Überprüfen und Hochladen eines Pakets.

  • Visual C++-Projekte verwenden jetzt pch.h und pch.cpp, um vorkompilierte Headerinformationen aufzunehmen. Migrieren Sie die relevanten #include-Anweisungen von stdafx.h zu pch.h.

[Nach oben]

Wichtige Punkte der Interop-Migration

In der Windows Store-App-Version des Reise-Optimierers von Bing Maps konnten wir einen Großteil des JavaScript-Codes aus der ActiveX-Version verwenden. Der Hauptunterschied liegt darin, wie der HTML- und der JavaScript-Code auf die C++-Komponente verweisen.

Die ActiveX-Version verwendet das HTML-Tag object, um auf die C++-Komponente zu verweisen.

<object id="OptimizerControl" name="OptimizerControl" classid="CLSID:10FFAAB9-0E73-4C4D-8118-6225C7F2E692"></object>

Außerdem verwendet die ActiveX-Version den id-Wert, "OptimizerControl", um die COptimizerControl-Methoden aufzurufen.

Die Windows Store-App-Version des Reise-Optimierers von Bing Maps legt einen Projektverweis fest und verwendet eine globale Variable anstelle des object-Tags. Das Projektsystem führt die erforderlichen Schritte für die Suche und das Laden der C++-Komponente durch die JavaScript-App aus. Weitere Informationen zum Einrichten von Projektverweisen finden Sie unter Erstellen von Windows-Runtime-Komponenten in C++.

Die ActiveX-Version verwendet die ::-Syntax, um Ereignisse zu behandeln.

// Event handler for progress notifications from the control.
function document.OptimizerControl::ProgressCallback(message) {
   // Set message.
   ProgressMessageText.innerHTML = message;
}

Die Windows Store-App-Version nutzt asynchrone Verarbeitung und Ziele, um auf Antworten von der C++-Komponente zu reagieren. Weitere Informationen zu diesem Prozess finden Sie unter Empfangen von Daten von der C++-Komponente.

[Nach oben]