Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Это важно
Дополнительные сведения о настройке Visual Studio для разработки на C++/WinRT, включая установку и использование расширения Visual Studio для C++/WinRT (VSIX) и пакета NuGet (которые вместе предоставляют поддержку шаблона проекта и сборки), см. в разделе Поддержка Visual Studio для C++/WinRT.
Чтобы ускорить использование C++/WinRT, в этом разделе рассматривается простой пример кода на основе нового консольного приложения Windows (C++/WinRT) проекта. В этом разделе также показано, как добавить поддержку C++/WinRT в проект классического приложения Windows.
Замечание
Хотя рекомендуется разрабатывать с помощью последних версий Visual Studio и пакета SDK для Windows, Если вы используете Visual Studio 2017 (версия 15.8.0 или более позднюю версию) и предназначение для пакета SDK для Windows версии 10.0.17134.0 (Windows 10 версии 1803), то созданный проект C++/WinRT может не скомпилироваться с ошибкой "ошибка C3861: "from_abi". идентификатор не найден" и с другими ошибками, возникающими в base.h. Решение заключается в том, чтобы выбрать более позднюю (более соответствующую) версию пакета SDK для Windows или задать свойство проекта языка C/C++>языкового>: (кроме того, если /permissive- отображается в свойстве проекта языке C/C++>языке>командной строке в дополнительных параметров, затем удалите его).
Быстрый старт по C++/WinRT
Создайте проект консольного приложения Windows (C++/WinRT).
Измените pch.h
и main.cpp
, чтобы они выглядели следующим образом.
// pch.h
#pragma once
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Web.Syndication.h>
#include <iostream>
// main.cpp
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;
int main()
{
winrt::init_apartment();
Uri rssFeedUri{ L"https://blogs.windows.com/feed" };
SyndicationClient syndicationClient;
syndicationClient.SetRequestHeader(L"User-Agent", L"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
SyndicationFeed syndicationFeed = syndicationClient.RetrieveFeedAsync(rssFeedUri).get();
for (const SyndicationItem syndicationItem : syndicationFeed.Items())
{
winrt::hstring titleAsHstring = syndicationItem.Title().Text();
// A workaround to remove the trademark symbol from the title string, because it causes issues in this case.
std::wstring titleAsStdWstring{ titleAsHstring.c_str() };
titleAsStdWstring.erase(remove(titleAsStdWstring.begin(), titleAsStdWstring.end(), L'™'), titleAsStdWstring.end());
titleAsHstring = titleAsStdWstring;
std::wcout << titleAsHstring.c_str() << std::endl;
}
}
Давайте рассмотрим краткий пример кода, приведенный выше по частям, и объясним, что происходит в каждой части.
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Web.Syndication.h>
При использовании параметров проекта по умолчанию включенные заголовки приходят из пакета SDK для Windows в папке %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt
. Visual Studio включает этот путь в макрос IncludePath . Но нет строгой зависимости от пакета SDK для Windows, так как ваш проект (с помощью cppwinrt.exe
средства) генерирует те же заголовки в папку $(GeneratedFilesDir) вашего проекта. Они будут загружены из этой папки, если их не удается найти в другом месте или если вы измените параметры проекта.
Заголовки содержат API Windows, проецируемые в C++/WinRT. Другими словами, для каждого типа Windows C++/WinRT определяет удобный для C++ эквивалент (называемый проецируемым типом). Проецируемый тип имеет то же полное имя, что и тип Windows, но он помещается в пространство имен C++ winrt. Добавление этих элементов в предварительно скомпилированные заголовки сокращает время добавочной сборки.
Это важно
Каждый раз, когда вы хотите использовать тип из пространств имен Windows, необходимо #include
соответствующий файл заголовка пространства имен C++/WinRT Windows, как показано выше.
соответствующий заголовок совпадает с тем же именем, что и пространство имен типа. Например, чтобы использовать проекцию C++/WinRT для класса среды выполнения Windows::Foundation::Collections::P ropertySet, включите заголовок winrt/Windows.Foundation.Collections.h
.
Обычно заголовок проекции C++/WinRT автоматически включает файлы заголовков, относящиеся к пространству имен. Например, winrt/Windows.Foundation.Collections.h
включает winrt/Windows.Foundation.h
. Но вы не должны полагаться на это поведение, так как это детали реализации, которые изменяются с течением времени. Необходимо явно включить все заголовки, которые вам нужны.
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;
Директивы using namespace
являются необязательными, но удобными. Приведенный выше шаблон для таких директив (разрешающий поиск неквалифицированных имен для любых элементов в пространстве имен winrt) подходит при запуске нового проекта и C++/WinRT является единственной языковой проекцией в этом проекте. Если, с другой стороны, вы смешиваете код C++/WinRT с кодом C++/CX и/или кодом двоичного интерфейса приложения SDK (ABI) (вы либо переносите из одной или обеих моделей, либо взаимодействуете с ними), то см. разделы взаимодействие между C++/WinRT и C++/CX, переход на C++/WinRT из C++/CX, и взаимодействие между C++/WinRT и ABI.
winrt::init_apartment();
Вызов winrt::init_apartment инициализирует поток в среде выполнения Windows, по умолчанию в многопоточном аппартаменте. Вызов также инициализирует COM.
Uri rssFeedUri{ L"https://blogs.windows.com/feed" };
SyndicationClient syndicationClient;
Стек выделяет два объекта: они представляют uri блога Windows и клиент синдикации. Мы создаем URI с простым строковым литералом (см. обработку строк в C++/WinRT для получения дополнительных способов работы со строками).
SyndicationFeed syndicationFeed = syndicationClient.RetrieveFeedAsync(rssFeedUri).get();
SyndicationClient::RetrieveFeedAsync — пример асинхронной функции среды выполнения Windows. Пример кода получает объект асинхронной операции из RetrieveFeedAsync, и вызывает get на этом объекте, чтобы приостановить выполнение вызывающего потока и ожидать результата (в данном случае это веб-канал синдикации). Дополнительные сведения о параллелизме, а также о неблокирующих техниках, см. в Параллелизм и асинхронные операции с C++/WinRT.
for (const SyndicationItem syndicationItem : syndicationFeed.Items()) { ... }
SyndicationFeed.Items — это диапазон, определяемый итераторами, возвращаемыми функциями начало и конец (или их константными, обратными и константно-обратными вариантами). Из-за этого можно перечислить items с помощью инструкции for
на основе диапазона или с помощью функции шаблона std::for_each. Каждый раз, когда вы выполняете итерацию по коллекции Windows Runtime, вам потребуется #include <winrt/Windows.Foundation.Collections.h>
.
winrt::hstring titleAsHstring = syndicationItem.Title().Text();
// Omitted: there's a little bit of extra work here to remove the trademark symbol from the title text.
std::wcout << titleAsHstring.c_str() << std::endl;
Возвращает текст заголовка веб-канала как объект winrt::hstring (дополнительные сведения см. в разделе Обработка строк в C++/WinRT). Затем
Как видно, C++/WinRT поощряет современные и классные выражения C++, такие как syndicationItem.Title().Text()
. Это другой и более чистый стиль программирования от традиционного COM-программирования. Вам не нужно напрямую инициализировать COM, а также работать с указателями COM.
Кроме того, вам не нужно обрабатывать коды возврата HRESULT. C++/WinRT преобразует ошибки HRESULTs в исключения, такие как winrt::hresult-error для естественного и современного стиля программирования. Дополнительные сведения об обработке ошибок и примерах кода см. в статье об обработке ошибок с помощью C++/WinRT.
Изменение проекта классического приложения Windows для добавления поддержки C++/WinRT
Некоторые настольные проекты (например, шаблоны WinUI 3 в Visual Studio) имеют встроенную поддержку C++/WinRT.
Но в этом разделе показано, как добавить поддержку C++/WinRT в любой проект классического приложения Windows, который вы могли бы иметь. Если у вас нет существующего проекта классического приложения Windows, вы можете выполнить эти действия, сначала создав его. Например, откройте Visual Studio и создайте проект Visual C++>Windows Desktop>Windows Desktop Application.
При необходимости можно установить
Установить свойства проекта
Перейдите к свойству проекта Общие>Версия Windows SDKи выберите Все конфигурации и Все платформы. Убедитесь, что версии пакета SDK для Windows установлено значение 10.0.0.17134.0 (Windows 10 версии 1803) или более поздней версии.
Убедитесь, что вы не пострадали от Почему мой новый проект не компилируется?.
Так как C++/WinRT использует функции стандарта C++17, задайте свойство проекта C/C++>Язык>Стандарт языка C++ на стандарт ISO C++17 (/std:c++17).
Предварительно скомпилированные заголовки
Шаблон проекта по умолчанию создает предварительно скомпилируемый заголовок для вас с именем framework.h
или stdafx.h
. Переименуйте это в pch.h
. Если у вас есть stdafx.cpp
файл, переименуйте его pch.cpp
в . Задайте свойству проекта C/C++>Предварительно Скомпилированные Заголовки>Предварительно Скомпилированный Заголовок, установите значение Создать (/Yc), а также для Предварительно Скомпилированного Файла Заголовков — pch.h.
Найдите и замените все #include "framework.h"
(или #include "stdafx.h"
) на #include "pch.h"
.
В pch.h
включать winrt/base.h
.
// pch.h
...
#include <winrt/base.h>
Связывание
Проекция языка C++/WinRT зависит от определенных несвязанных (не членских) функций и точек входа среды выполнения Windows, которые требуют связывания с управляющей библиотекой WindowsApp.lib. В этом разделе описано три способа удовлетворения компоновщика.
Первым вариантом является добавление в проект Visual Studio всех свойств и целевых объектов MSBuild C++/WinRT. Для этого установите пакет NuGet Microsoft.Windows.CppWinRT в ваш проект. Откройте проект в Visual Studio, щелкните на Проект>Управление пакетами NuGet...>Просмотр, введите или вставьте Microsoft.Windows.CppWinRT в поле поиска, выберите нужный элемент из результатов, а затем нажмите на Установить для добавления пакета в этот проект.
Вы также можете использовать настройки ссылок проекта для явной привязки WindowsApp.lib
. Кроме того, вы можете сделать это в исходном коде (например, в pch.h
, например).
#pragma comment(lib, "windowsapp")
Теперь вы можете скомпилировать и связать, а также добавить код C++/WinRT в ваш проект (например, код, аналогичный тому, что показан в разделе Краткое начало работы с C++/WinRT выше).
Три основных сценария для C++/WinRT
При использовании и ознакомлении с C++/WinRT и работе с остальной документацией вы, скорее всего, заметите, что существует три основных сценария, как описано в следующих разделах.
Использование API и типов Windows
Другими словами, с помощью, или с помощью вызова API. Например, вызовы API для обмена данными с помощью Bluetooth; для потоковой передачи и представления видео; интеграция с оболочкой Windows; и т. д. C++/WinRT полностью и бескомпромиссно поддерживает эту категорию сценария. Дополнительные сведения см. в статье Использование API с C++/WinRT.
Разработка API и типов Windows
Другими словами, предоставляет API и типы. Например, создание типов API, описанных в вышеупомянутом разделе, графические API, API для хранилища и файловой системы, сетевые API и так далее. Дополнительные сведения см. в статье Авторские API с помощью C++/WinRT.
Создание API с использованием C++/WinRT требует большего вовлечения, чем их использование, так как необходимо применять IDL для определения структуры API, прежде чем его реализовать. В элементах управления XAML есть пошаговое руководство, которое показывает, как привязать к свойству C++/WinRT.
Приложения XAML
Этот сценарий предназначен для создания приложений и элементов управления на платформе пользовательского интерфейса XAML. Работа в приложении XAML сводится к сочетанию использования и разработки. Но поскольку XAML является доминирующим фреймворком пользовательского интерфейса в Windows сегодня, и его влияние на среду выполнения Windows пропорционально этому, и поэтому она заслуживает своей собственной категории сценариев.
Помните, что XAML лучше всего работает с языками программирования, которые предлагают отражение. В C++/WinRT иногда требуется выполнить небольшую дополнительную работу, чтобы взаимодействовать с платформой XAML. Все эти случаи рассматриваются в документации. Хорошие места для начала — элементы управления XAML; привязка к свойству C++/WinRT и пользовательским (шаблонным) элементам управления XAML с помощью C++/WinRT.
Примеры приложений, написанных на C++/WinRT
См. раздел " Где можно найти примеры приложений C++/WinRT?".
Важные API
- Метод SyndicationClient::RetrieveFeedAsync
- свойство SyndicationFeed.Items
- winrt::hstring структура
- winrt::hresult-error структура