Перенос существующего кода в примере 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++.
[Наверх]