Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Это важно
Сведения о настройке Visual Studio для разработки C++/WinRT, включая установку и использование расширения C++/WinRT Visual Studio (VSIX) и пакета NuGet (которые вместе предоставляют поддержку шаблона проекта и сборки),см. Visual Studio поддержку C++/WinRT.
Чтобы ускорить работу с помощью C++/WinRT, в этом разделе описывается простой пример кода на основе нового проекта консольного приложения Windows (C++/WinRT). В этом разделе также показано, как добавить поддержку C++/WinRT в проект приложения Windows Desktop.
Note
Хотя мы рекомендуем разрабатывать с использованием последних версий Visual Studio и Windows SDK, если вы используете Visual Studio 2017 (версии 15.8.0 или более поздней) и ориентируетесь на Windows SDK версии 10.0.17134.0 (Windows 10, версия 1803), то вновь созданный проект C++/WinRT может не скомпилироваться с ошибкой "error C3861: 'from_abi': identifier not found", а также с другими ошибками, возникающими в base.h. Решение состоит в том, чтобы либо использовать более позднюю (лучше соответствующую стандарту) версию Windows SDK, либо задать для свойства проекта C/C++>Language>Conformance mode: No (также, если /permissive- отображается в свойстве проекта C/C++>Language>Command Line в разделе Additional Options, удалите его).
Краткое введение в 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. Но строгой зависимости от Windows SDK нет, поскольку ваш проект (с помощью средства cppwinrt.exe) генерирует эти же заголовочные файлы в папке $(GeneratedFilesDir) вашего проекта. Они будут загружены из этой папки, если их не удается найти в другом месте или если вы измените параметры проекта.
Заголовки содержат Windows API, проецируемые в C++/WinRT. Другими словами, для каждого типа Windows C++/WinRT определяет эквивалент, удобный для C++ (называемый проецируемым типом). Проецируемый тип имеет то же полное имя, что и тип Windows, но он помещается в пространство имен winrt C++. Добавление этих элементов в предварительно скомпилированные заголовки сокращает время добавочной сборки.
Это важно
Если вы хотите использовать тип из пространств имен 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 и/или кодом ABI (двоичного интерфейса приложения) SDK (то есть переносите код из одной или обеих этих моделей либо обеспечиваете взаимодействие с ними), см. разделы Взаимодействие между 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 — это диапазон, определенный итераторами, возвращаемыми из начальных и конечных функций (или их констант, обратных и константных обратных вариантов). Из-за этого можно перечислить элементы с помощью инструкции на основе for диапазона или с функцией шаблона std::for_each . Каждый раз, когда вы перебираете коллекцию среда выполнения Windows таким образом, вам потребуется #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). Затем hstring выводится через функцию c_str , которая отражает шаблон, используемый со строками стандартной библиотеки C++.
Как видно, 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.
При необходимости можно установить расширение C++/WinRT Visual Studio (VSIX) и пакет NuGet. Дополнительные сведения см. в статье «Поддержка C++/WinRT в Visual Studio».
Настройка свойств проекта
Перейдите к свойству проекта Общие>Версия Windows SDK и выберите Все конфигурации и Все платформы. Убедитесь, что версия пакета SDK для Windows имеет значение 10.0.17134.0 (Windows 10 версии 1803) или более поздней.
Убедитесь, что вас не касается проблема, описанная в Почему мой новый проект не компилируется?.
Так как C++/WinRT использует возможности стандарта C++17, установите для свойства проекта C/C++>Language>C++ Language Standard значение ISO C++17 Standard (/std:c++17).
Предварительно скомпилированные заголовки
Шаблон проекта по умолчанию создает предварительно скомпилируемый заголовок для вас с именем framework.hили stdafx.h. Переименуйте это в pch.h. Если у вас есть stdafx.cpp файл, переименуйте его pch.cppв . Задайте для свойства проекта C/C++>Предварительно скомпилированные заголовки>Предварительно скомпилированный заголовок значение Create (/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, щелкните Project>Manage NuGet Packages...>Browse, введите или вставьте Microsoft.Windows.CppWinRT в поле поиска, выберите элемент в результатах поиска, а затем нажмите Install, чтобы установить пакет для этого проекта.
Вы также можете использовать параметры ссылки проекта для явной ссылки WindowsApp.lib. Или вы можете сделать это в исходном коде (например, в pch.h) вот так.
#pragma comment(lib, "windowsapp")
Теперь вы можете компилировать и связать код C++/WinRT в проект (например, код, аналогичный приведенному в разделе быстрого запуска C++/WinRT , приведенном выше).
Три основных сценария для C++/WinRT
При использовании и ознакомлении с C++/WinRT и работе с остальной документацией вы, скорее всего, заметите, что существует три основных сценария, как описано в следующих разделах.
Использование API и типов Windows
Другими словами, использовать API или вызывать API. Например, вызовы API для обмена данными с помощью Bluetooth; для потоковой передачи и представления видео; для интеграции с оболочкой Windows и т. д. C++/WinRT полностью и бескомпромиссно поддерживает эту категорию сценария. Дополнительные сведения см. в разделе "Использование API с помощью C++/WinRT".
Разработка Windows API и типов
Другими словами, создание 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
Связанные темы
Windows developer