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