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


Перенос существующего кода в примере 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. Вместо объекта HRESULT мы используем фактический тип возвращаемого значения Windows::Foundation::Collections::IMap<K, V>. Кроме того, для каждого из параметров мы используем соответствующие типы Среда выполнения 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, для реализации некоторых элементов компонента нам пришлось использовать альтернативные механизмы. Например, для взаимодействия с HTTP-серверами в версии ActiveX элемента управления используется класс 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++.

[Наверх]