共用方式為


在使用 Bing 地圖服務路線最佳化程式範例中 JavaScript 和 C++ 的互通性

Bing 地圖服務路線最佳化程式可使用 JavaScript 定義 UI 與 C++,以執行旅程最佳化。本文件說明 Bing 地圖服務路線最佳化程式範例的 JavaScript 和 C++ 組件如何相互操作。文中說明 JavaScript 元件如何初始化 C++ 元件並將資料傳送給它,以及 C++元件如何將資料傳回給 JavaScript 元件。JavaScript 和 C++ 元件在在使用 Bing 地圖服務路線最佳化程式範例中使用 JavaScript在使用 Bing 地圖服務路線最佳化程式範例中使用 C++ 文件中有詳細說明。

注意事項注意事項

提醒您,我們將 default.html、default.css 與 default.js 統稱為「本機內容」(Local Context),因為這些檔案雖然可參考 Windows 執行階段 (其中包括自訂 C++ Windows 執行階段元件),但卻無法存取 Web。我們將 web.html、web.css 與 web.js 統稱為「Web 內容」(Web Context),因為這些檔案雖然可存取 Web,卻無法存取 Windows 執行階段。Web 內容也可定義使用者介面。

注意事項注意事項

如需本文件的對應範例程式碼,請參閱 Bing 地圖服務路線最佳化程式範例

本文內容

  • 從 JavaScript 初始化 C++ 元件

  • 將資料傳送至 C++ 元件

  • 從 C++ 元件接收資料

  • 從 ActiveX 移轉

  • 後續步驟

從 JavaScript 初始化 C++ 元件

本機內容可宣告代表 C++ 元件與目前旅程最佳化作業的變數。

// The C++ component.
var tripOptimizer = null;

// The current asynchronous trip optimization.
var asyncOperation = null;

optimizerLoad 函式是在應用程式初始化期間呼叫的,可用以建立 TripOptimizer 物件。

function optimizerLoad() {
    "use strict";
    tripOptimizer = new TripOptimizerComponent.TripOptimizer();
}

Windows 執行階段可找出 TripOptimizer 物件並加以載入,因為 JavaScript Visual Studio 專案中包含 C++ 專案的參考。

[頂端]

將資料傳送至 C++ 元件

在使用 Bing 地圖服務路線最佳化程式範例中使用 JavaScript文件說明 Web 內容與本機內容的通訊方式。當使用者選取 [取得方向] 或 [取消] 按鈕時,Web 內容即會傳送訊息給本機內容,以在 C++ 元件中呼叫適當的 TripOptimizer 方法。例如,當使用者選擇 [取得方向] 時,Web 內容會傳送含有字串 "optimizeTrip" 的訊息給本機內容。當使用者選擇 [取消] 時,Web 內容則會傳送字串 "cancel"。下列程式碼將說明本機內容從 Web 內容接收這些訊息的情形。

function receiveMessage(message) {
    "use strict";
    // Verify event origin.
    if (message.origin !== "ms-appx-web://microsoft.sdksamples.tripoptimizer.js") {
        return;
    }

    var data = JSON.parse(message.data);
    if (data.invoke === "load") {
        optimizerLoad();
    } else if (data.invoke === "optimizeTrip") {
        optimizerOptimizeTrip(
            data.locations,
            data.travelMode,
            data.optimize,
            data.bingMapsKey,
            data.alpha,
            data.beta,
            data.rho,
            data.iterations,
            data.parallel);
    } else if (data.invoke === "cancel") {
        optimizerCancel();
    } else if (data.invoke === "alert") {
            // Show message dialog.            
            new Windows.UI.Popups.MessageDialog(data.message).showAsync().then();
    }
}

optimizerOptimizeTrip 函式會將參數從 Web 內容轉送至 C++ 元件。

function optimizerOptimizeTrip(locations, travelMode, optimize, bingMapsKey, alpha, beta, rho, iterations, parallel) {
    "use strict";
    asyncOperation = tripOptimizer.optimizeTripAsync(locations, travelMode, optimize, bingMapsKey,
        alpha, beta, rho, iterations, parallel);

此範例也會設定 asyncOperation 變數。設定了此變數,我們即可在使用者選擇 [取消] 時取消作業。

function optimizerCancel() {
    "use strict";
    if (asyncOperation !== null) {
        asyncOperation.cancel();
    }
}
注意事項注意事項

C++ 元件中的 TripOptimizer::OptimizerTripAsync 方法會以 TripOptimizer.optimizerTripAsync 的形式公開至 JavaScript (第一個字母會變更為小寫,以符合標準 JavaScript 命名慣例)。

[頂端]

從 C++ 元件接收資料

C++ 元件中的 TripOptimizer::OptimizerTripAsync 方法會以非同步方式運作。因此,應用程式的 JavaScript 組件必須能夠在資料可用時加以處理。在非同步作業完成、擲回錯誤或報告進度時,JavaScript 組件可使用「承諾」(Promises) 來回應。下列範例說明 optimizerOptimizeTrip 函式如何定義 TripOptimizer::OptimizeTripAsync 呼叫的完成、錯誤與進度回呼。

function optimizerOptimizeTrip(locations, travelMode, optimize, bingMapsKey, alpha, beta, rho, iterations, parallel) {
    "use strict";
    asyncOperation = tripOptimizer.optimizeTripAsync(locations, travelMode, optimize, bingMapsKey,
        alpha, beta, rho, iterations, parallel);

    asyncOperation.then(
        function (result) {
            if (result !== null) {
                // If the result contains certain keys, then we know that the results contain
                // the optimize route.
                if (result.size === 2 && result.hasKey("locations") && result.hasKey("displayNames")) {
                    routeCallback(result);
                }
                    // Otherwise, we know that the component is asking us to resolve ambiguous locations.
                else {
                    locationsCallback(result);
                }
            }
            else {
                canceledCallback();
            }
            asyncOperation = null;
        },
        function (error) {
            if (error.description === "Canceled") {
                canceledCallback();
            }
            else {
                errorCallback("Error: " + error.message);
            }
            asyncOperation = null;
        },
        function (progress) {
            progressCallback(progress);
        }
        );
}

請注意,當使用者選擇 [取消] 時,C++ 元件即會取消目前的作業。執行階段會為該作業呼叫錯誤處理常式。它會將錯誤的 description 欄位設定為「已取消」,以指出這是取消所造成的結果。如需如何以 JavaScript 使用非同步作業的詳細資訊,請參閱Asynchronous programming

本機內容在接收到非同步作業的進度或結果時,會將事件資料轉送給 Web 內容,讓 Web 內容能夠更新 UI。例如,progressCallback 函式會在傳送給 Web 內容的訊息中,隨附傳送字串 "progressCallback"。

// Event handler for progress notifications from the Windows Runtime component.
function progressCallback(info) {
    "use strict";
    var message = { "invoke": "progressCallback", "message": info };
    window.parent.frames.mapFrame.postMessage(JSON.stringify(message), "*");
}

下列範例將說明 Web 內容的 receiveMessage 函式。此函式會接收來自本機內容的訊息。

// Receives a message from the local context.
function receiveMessage(message) {
    "use strict";
    // Verify event origin.
    if (message.origin !== "ms-appx://microsoft.sdksamples.tripoptimizer.js") {
        return;
    }

    var data = JSON.parse(message.data);
    if (data.invoke === "progressCallback") {
        progressCallback(data.message);
    } else if (data.invoke === "locationsCallback") {
        locationsCallback(JSON.parse(data.locationOptions));
    } else if (data.invoke === "routeCallback") {
        routeCallback(data.locations, data.displayNames);
    } else if (data.invoke === "canceledCallback") {
        canceledCallback();
    } else if (data.invoke === "errorCallback") {
        errorCallback(data.message);
    }
}

對於 "progressCallback" 訊息,Web 內容會呼叫 progressCallback 函式,更新 UI 以顯示進度訊息。

// Event handler for progress notifications from the control.
function progressCallback(message) {
    "use strict";
    // Set message.
    progressMessageText.innerHTML = message;
}

[頂端]

從 ActiveX 移轉

如需如何從 ActiveX 版本的 Bing 地圖服務路線最佳化程式移轉至 Windows 市集應用程式的詳細資訊,請參閱移轉使用 Bing 地圖服務之路線最佳化程式範例中的程式碼

[頂端]

後續步驟

本文說明我們如何使用 JavaScript 與 C++ 建立完整的 Windows 市集應用程式。您可以考慮搭配使用 C++ 元件與 JavaScript 應用程式,讓您已撰寫並測試的程式碼充分發揮功效,並提升效能。

[頂端]