Поделиться через


Перенос существующего кода в примере Bing Maps Trip Optimizer

В этом документе рассматриваются некоторые ключевые рекомендации, которым мы следовали при переходе от версии Bing Maps Trip Optimizer на базе ActiveX к приложению Магазин Windows. Этот документ не содержит полного описания процедуры переноса имеющегося кода в Среда выполнения Windows. В нем описываются лишь основные моменты и подчеркиваются важные факторы, которые следовало учитывать.

Примечание

Пример кода, который соответствует этому документу, находится в статьях Пример приложения Bing Maps Trip Optimizer (приложение Магазин Windows) и Приложение Bing Maps Trip Optimizer (веб-приложение ActiveX).

Содержание этой статьи

  • Основные особенности переноса JavaScript

  • Основные особенности переноса C++

  • Основные особенности переноса функций взаимодействия

Основные особенности переноса JavaScript

Версия ActiveX приложения Bing Maps Trip Optimizer содержит один файл с кодом пользовательского интерфейса (OptimizerControl.htm). Как указано в этой документации, при переносе с целью использования Среда выполнения Windows необходимо было создать отдельные контексты для компонентов, которые взаимодействуют с веб-средой, и компонентов, которые взаимодействуют с Среда выполнения Windows. Мы должны были написать дополнительный код, чтобы обеспечить взаимодействие контекстов. В документе Features and restrictions by context более подробно описаны различия между локальным контекстом и веб-контекстом.

В версии приложения Магазин Windows нам удалось использовать большую часть кода исходной версии. Основное отличие состоит в том, что, поскольку приложение Магазин Windows больше не ссылается на элемент управления ActiveX, мы заменили элемент object глобальной переменной, которая представляет компонент C++. Этот механизм более подробно рассматривается в разделе Взаимодействие кода JavaScript и C++ в примере Bing Maps Trip Optimizer.

Такие методы окна, как alert, prompt и open, не работают в JavaScript-приложениях Магазин Windows. В версии ActiveX элемента управления метод alert используется для оповещения пользователя о проблеме, например если было введено более 25 расположений. Версия приложения Магазин Windows использует класс Windows.UI.Popups.MessageDialog для отображения сообщений пользователю.

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

Поскольку после отображения диалогового окна сообщения никакие действия не выполняются, оператор then остается пустым. Дополнительные сведения о работе с асинхронными операциями на языке JavaScript см. в разделе Asynchronous programming.

Дополнительные сведения о некоторых отличиях в использовании имеющихся функций HTML в JavaScript-приложении Магазин Windows см. в разделе HTML, CSS, and JavaScript features and differences.

В версии приложения ActiveX для отображения карты в пользовательском интерфейсе используется элемент управления Bing Maps AJAX версии 6.3. Версия приложения Магазин Windows использует элемент управления Bing Maps AJAX версии 7.0. Обновление с версии 6.3 до версии 7.0 не является обязательным; в приложении Магазин Windows можно использовать и версию 6.3. В этой реализации мы выбрали версию 7.0, поскольку она отличается большей производительностью и лучшей поддержкой сенсорного ввода, а нам необходимо было показать новый способ получения информации из Bing Maps.

[Наверх]

Основные особенности переноса C++

При создании компонентов Магазин Windows с помощью C++/CX инфраструктура, необходимая для взаимодействия с другими компонентами и языками, обрабатывается компилятором и Среда выполнения Windows. При переносе версии ActiveX элемента управления в компонент Магазин Windows мы удалили код инфраструктуры, необходимый для реализации настраиваемого COM-интерфейса. Например, компонент Среда выполнения Windows не требует IDL-файлов, которые определяют интерфейсы и события, предоставляемые компонентом. Кроме того, по возможности мы сохраняли особенности реализации, использующие чистый машинный код. Использование C++/CX и Среда выполнения Windows является обязательным, только если элемент управления взаимодействует с другими объектами и компонентами Среда выполнения Windows.

При переносе элементов управления ActiveX в элементы управления, использующие Среда выполнения Windows, старайтесь следовать приведенным ниже инструкциям.

Совет

Многие из этих инструкций предполагают работу с синтаксисом C++/CX.Дополнительные сведения об этом синтаксисе см. в разделе Справочник по языку C++ (C++/CX).

  • Для создания проекта Visual Studio используйте шаблон Библиотека классов WinRT.

  • Добавьте в свой класс Среда выполнения Windows методы и свойства из открытого интерфейса элемента управления ActiveX. Преобразуйте типы параметров и возвращаемых значений, чтобы сделать их совместимыми с Среда выполнения Windows. Например, в файле TripOptimizerImpl.idl определен интерфейс IOptimizerControl для элемента управления 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();
    };
    

    Для компонента Магазин Windows ниже приведено объявление метода TripOptimizer::OptimizeTripAsync в компоненте Среда выполнения Windows. Мы используем фактический тип возвращаемого значения, 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.

  • Добавьте в свой класс Среда выполнения Windows открытые события из элемента управления ActiveX. Как и в случае методов и свойств, преобразуйте типы параметров и возвращаемых значений, чтобы сделать их совместимыми с Среда выполнения Windows.

    В этой реализации нам удалось избавиться от всех событий, определенных в версии ActiveX, поскольку все эти действия обрабатываются другими способами. Например, нам больше не нужно определять событие завершения, поскольку мы возвращаем результат непосредственно как часть объекта IAsyncOperationWithProgress<TResult, TProgress>, возвращаемого методом TripOptimizer::OptimizeRouteAsync. Обратные вызовы ошибок и хода выполнения также обрабатываются с помощью объекта IAsyncOperationWithProgress<TResult, TProgress>. Дополнительные сведения о том, как часть приложения, написанная на JavaScript, использует асинхронные операции, см. в разделе Взаимодействие кода JavaScript и C++ в примере Bing Maps Trip Optimizer.

  • При определении членов данных для класса Среда выполнения Windows выбирайте соответствующие стандартные типы C++ и Среда выполнения Windows.

    Например, класс COptimizerControl использует для хранения строковых значений типы COM, такие как _bstr_t.

    В версии приложения Магазин Windows для хранения строковых значений мы использовали стандартный строковый тип C++ std::wstring. Например, в методе TripOptimizerImpl::OptimizeTripAsync параметры Windows::Foundation::Collections::IVector<T> и Platform::String преобразуются в std::vector и std::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::Foundation::Collections::IMap<K, V> и Windows::Foundation::Collections::IVector<T>) полезны при регулярном обмене данными между Среда выполнения Windows и кодом, поскольку в этом случае приложению требуется выполнять меньше преобразований строкового типа. В противном случае можно использовать стандартные типы коллекций C++, такие как std::map и std::vector.

    Особенности реализации элемента управления более подробно описаны в разделе Рабочий процесс компонента.

  • Для определения асинхронных методов используйте интерфейсы Windows::Foundation::IAsyncAction, Windows::Foundation::IAsyncActionWithProgress<TProgress>, Windows::Foundation::IAsyncOperation<TResult> или Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress>. Для создания этих объектов из компонента или приложения Магазин Windows, написанного на языке C++, рекомендуется использовать функцию concurrency::create_async.

  • Старайтесь использовать существующий код в максимально возможном объеме. Нам удалось перенести особенности реализации, такие как алгоритм оптимизации "колония муравьев", внеся в код минимальные изменения или оставив код неизменным. Но поскольку приложения Магазин Windows могут использовать подмножества API Win32 и COM, для реализации некоторых элементов компонента нам пришлось использовать альтернативные механизмы. Например, в версии элемента управления ActiveX для взаимодействия с HTTP-серверами используется IXMLHTTPRequest. В компоненте C++ используется интерфейс IXMLHTTPRequest2, который является рекомендуемым способом взаимодействия с HTTP-серверами в приложениях Магазин Windows. Для обработки XML-отклика служб Bing Maps элемент управления ActiveX использует XmlLite. В компоненте Магазин Windows используется класс Среда выполнения Windows XmlDocument, поскольку его легко использовать и требовалось продемонстрировать обновление существующего кода модели COM для использования типов Среда выполнения Windows. Однако если в приложении Магазин Windows доступен существующий код Win32 или COM, можно продолжать использовать его.

    Дополнительные сведения об использовании Win32 и модели COM в приложении Магазин Windows см. в разделе Win32 и модель COM в приложениях для Магазина Windows.

    Важно!

    При использовании Win32 и COM в приложении Магазин Windows соответствующий код может выполняться в среде разработки, но, возможно, его распространение в Магазин Windows не будет одобрено.Поэтому рекомендуется периодически запускать верификатор приложений, чтобы следить за тем, что приложение успешно проходит проверку.Дополнительные сведения см. в разделах Подготовка приложения для Магазина Windows и Практическое руководство. Установка, проверка и отправка пакета.

  • Для хранения предварительно откомпилированных заголовков в проектах Visual C++ используются файлы pch.h и pch.cpp. Перенесите соответствующие директивы #include из stdafx.h в pch.h.

[Наверх]

Основные особенности переноса функций взаимодействия

В версии приложения Bing Maps Trip Optimizer Магазин Windows нам удалось использовать большую часть кода JavaScript из версии ActiveX. Основное отличие состоит в том, как код HTML и JavaScript ссылается на компонент C++.

В версии ActiveX для ссылки на компонент C++ используется HTML-тег object.

<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++. Настройка ссылок проекта более подробно описана в статье Создание компонентов среды выполнения Windows в C++.

Для обработки событий в версии ActiveX используется синтаксис ::.

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

Версия приложения Магазин Windows использует асинхронную обработку и должна реагировать на отклики компонента C++. Этот процесс поясняется в разделе Получение данных из компонента C++.

[Наверх]