共用方式為


在 Bing 地圖服務路線最佳化程式範例中移轉現有程式碼

本文件特別說明當我們從 ActiveX 版本的 Bing 地圖服務路線最佳化程式移轉至 Windows 市集應用程式時所遵循的一些主要方針。本文件不提供如何將現有程式碼移轉至 Windows 執行階段的完整說明。但是會特別說明我們的經驗以及我們必須注意的重要層面。

注意事項注意事項

Bing 地圖服務路線最佳化程式範例 (Windows 市集應用程式) 和 Bing Maps Trip Optimizer (ActiveX Web 應用程式) 中可找到與本文件對應的範例程式碼。

本文內容

  • JavaScript 移轉關鍵點

  • C++ 移轉關鍵點

  • Interop 移轉關鍵點

JavaScript 移轉關鍵點

ActiveX 版本的 Bing Maps Trip Optimizer 會將一個程式碼檔案 (OptimizerControl.htm) 用於 UI。如本文件所述,當我們轉為使用 Windows 執行階段時,我們必須針對與 Web 互動的元件以及與 Windows 執行階段互動的元件產生個別的內容。我們必須撰寫額外的程式碼,才能讓內容進行通訊。Features and restrictions by context這份文件進一步說明本機和 Web 內容之間的差異。

我們能夠在 Windows 市集應用程式版本中使用原始版本的大部分程式碼。其中一個主要差異是因為 Windows 市集應用程式不再參考 ActiveX 控制項,我們便以表示 C++ 元件的全域變數取代 object 項目。在 Bing 地圖服務路線最佳化程式範例中 JavaScript 和 C++ 之間的交互作業中會更詳細說明這個機制。

在 JavaScript Windows 市集應用程式中,視窗方法 (例如 alertpromptopen) 無法運作。ActiveX 版本的控制項會使用 alert 來通知使用者有問題,例如輸入超過 25 個位置的時候。Windows 市集版本的應用程式會使用 Windows.UI.Popups.MessageDialog 類別來對使用者顯示訊息。

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

因為在訊息對話方塊顯示之後,沒有要執行的動作,所以 then 陳述式是空的。如需如何以 JavaScript 使用非同步作業的詳細資訊,請參閱Asynchronous programming

如需有關如何在 JavaScript Windows 市集應用程式中使用現有 HTML 功能的差異詳細資訊,請參閱 HTML, CSS, and JavaScript features and differences

ActiveX 版本的應用程式會使用 Bing Maps AJAX Control 6.3 版,在 UI 上顯示地圖。Windows 市集應用程式版本會使用 Bing Maps AJAX Control 7.0 版。不一定要從 6.3 版升級到 7.0 版,您可以在 Windows 市集應用程式中使用 6.3 版。我們在此實作中選擇了 7.0 版,因為它包含效能改進和改良的觸控支援,而且我們想要示範從 Bing Maps 取得資訊的較新方法。

[頂端]

C++ 移轉關鍵點

當您使用 C++/CX 建立 Windows 市集元件時,編譯器和 Windows 執行階段會處理與其他元件和語言互通時所需的基礎結構。當我們將 ActiveX 版本的控制項移轉到 Windows 市集元件時,我們能夠移除實作自訂 COM 介面時所需的基礎結構程式碼。例如,Windows 執行階段元件不需要 IDL 檔案,該檔案定義元件所提供的介面和事件。此外,我們盡可能維護使用純機器碼的實作詳細資料。只有當控制項與其他 Windows 執行階段物件和元件互動時,才需要使用 C++/CX 和 Windows 執行階段。

當您將 ActiveX 控制項移轉到使用 Windows 執行階段的控制項時,請考慮下列方針。

提示

其中許多方針都涉及使用 C++/CX 語法。如需此語法的詳細資訊,請參閱 Visual C++ 語言參考 (C++/CX)

  • 使用 [WinRT 類別庫] 範本建立 Visual Studio 專案。

  • 將公用介面方法和屬性從 ActiveX 控制項加入至 Windows 執行階段類別。轉換參數和傳回型別,以使用與 Windows 執行階段相容的型別。例如,TripOptimizerImpl.idl 會定義 ActiveX 控制項的 IOptimizerControl 介面。

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

    對於 Windows 市集元件,以下是 Windows 執行階段元件中的 TripOptimizer::OptimizeTripAsync 方法宣告。我們會使用實際傳回型別 Windows::Foundation::Collections::IMap<K, V>,而非 HRESULT。我們也會使用適合每一個參數的 Windows 執行階段型別。

    注意事項注意事項

    我們能夠在此實作中移除 CancelAsync 方法,因為取消功能是由 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);
    

    TripOptimizer::OptimizeTripAsync 方法會在建立 TripOptimizer 和 TripOptimizerImpl 類別一節中詳細說明。

  • 將公用事件從 ActiveX 控制項加入至 Windows 執行階段類別。如同方法和屬性一樣,轉換參數和傳回型別,以使用與 Windows 執行階段相容的型別。

    在此實作中,我們能夠移除 ActiveX 版本中定義的所有事件,因為這些動作都會經由其他方式處理。例如,您無須再定義完成事件,因為我們會直接傳回結果做為 TripOptimizer::OptimizeRouteAsync 所傳回之 IAsyncOperationWithProgress<TResult, TProgress> 物件的一部分。錯誤和進度回呼也是由 IAsyncOperationWithProgress<TResult, TProgress> 物件處理。如需應用程式的 JavaScript 組件如何使用非同步作業的詳細資訊,請參閱 Bing 地圖服務路線最佳化程式範例中 JavaScript 和 C++ 之間的交互作業

  • 當您定義 Windows 執行階段類別的資料成員時,請選擇適當的標準 C++ 和 Windows 執行階段型別。

    例如,COptimizerControl 類別會使用 COM 型別 (如 _bstr_t) 來保留字串值。

    在 Windows 市集版本的應用程式中,我們使用 std::wstring (標準 C++ 字串型別) 來保留字串值。例如,在 TripOptimizerImpl::OptimizeTripAsync 方法中,我們將 Windows::Foundation::Collections::IVector<T>Platform::String 參數轉會為 std::vectorstd::wstring,因為這些變數並未傳回到 Windows 執行階段元件。

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

    當您使用此慣例時,您可以更清楚地分辨哪些變數與 Windows 執行階段搭配使用。當您定期在 Windows 執行階段和程式碼之間通訊時,Windows 執行階段字串和集合型別 (例如 Windows::Foundation::Collections::IMap<K, V>Windows::Foundation::Collections::IVector<T>) 很有用,因為可以減少應用程式必須進行的字串型別轉換次數。否則,請考慮是否使用標準 C++ 集合型別 (例如 std::mapstd::vector)。

    控制項的實作詳細資料會在元件工作流程一節中詳細說明。

  • 使用 Windows::Foundation::IAsyncActionWindows::Foundation::IAsyncActionWithProgress<TProgress>Windows::Foundation::IAsyncOperation<TResult>Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress> 介面,協助定義非同步方法。concurrency::create_async 函式是從 C++ Windows 市集應用程式或元件建立這些物件的建議方式。

  • 盡可能使用現有的程式碼。我們能夠移轉實作詳細資料,例如蟻群最佳化演算法,只稍微修改程式碼,或完全不修改。但是,因為 Windows 市集應用程式可以使用 Win32 和 COM API 的子集,所以我們必須對元件的某些部分使用替代機制。例如,ActiveX 版本的控制項使用 IXMLHTTPRequest 來與 HTTP 伺服器通訊。在 C++ 元件中,我們會使用 IXMLHTTPRequest2,這是在 Windows 市集應用程式中與 HTTP 伺服器通訊的建議方式。為了處理來自 Bing 地圖服務的 XML 回應,ActiveX 控制項會使用 XmlLite。在 Windows 市集元件中,我們會使用容易使用的 Windows 執行階段 XmlDocument 類別,因為我們想要示範如何將現有的 COM 程式碼更新為使用 Windows 執行階段型別。不過,如果您有可在 Windows 市集應用程式中使用的現有 Win32 或 COM 程式碼,可以繼續使用它。

    如需如何在 Windows 市集應用程式中使用 Win32 和 COM 的詳細資訊,請參閱 適用於 Windows 市集應用程式的 Win32 和 COM (英文)。

    重要

    如果您在 Windows 市集應用程式中使用 Win32 和 COM,則有可能在開發環境中執行,但可能不會獲准從 Windows 市集發佈。因此,建議您經常執行應用程式驗證器,以確保您的應用程式通過驗證。如需詳細資訊,請參閱針對 Windows 市集準備您的應用程式 (英文) 和 HOW TO:安裝、驗證和上傳您的套件 (英文)。

  • Visual C++ 專案現在使用 pch.h 和 pch.cpp 來保留預先編譯的標頭資訊。將相關的 #include 陳述式從 stdafx.h 移轉至 pch.h。

[頂端]

Interop 移轉關鍵點

在 Windows 市集應用程式版本的 Bing Maps Trip Optimizer 中,我們能夠使用 ActiveX 版本大部分的 JavaScript 程式碼。主要差異在於 HTML 和 JavaScript 程式碼如何參考 C++ 元件。

ActiveX 版本使用 HTML object 標記來參考 C++ 元件。

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

因此,ActiveX 版本使用 id 值 (OptimizerControl) 來呼叫 COptimizerControl 方法。

Windows 市集應用程式版本的 Bing Maps Trip Optimizer 會設定專案參考並使用全域變數,而不使用 object 標記。專案系統會執行 JavaScript 應用程式要尋找和載入 C++ 元件所需的步驟。在 C++ 中建立 Windows 執行階段元件文章詳細說明如何設定專案參考。

ActiveX 版本使用 :: 語法來處理事件。

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

Windows 市集應用程式版本會使用非同步處理和承諾,以反應來自 C++元件 的回應。此處理序會在從 C++ 元件接收資料一節中說明。

[頂端]