Создайте "Hello, World!" Приложение UWP в C++/CX

Важно!

В этом руководстве используется язык C++/CX. Корпорация Майкрософт выпустила C++/WinRT. Это полностью соответствующая стандартам современная проекция языка C++17 для интерфейсов API среды выполнения Windows (WinRT). Дополнительные сведения об этом языке см. в разделе C++/WinRT.

В Microsoft Visual Studio вы можете использовать C++/CX для разработки приложения для Windows с пользовательским интерфейсом, определенным на языке XAML.

Примечание.

В этом руководстве используется Visual Studio Community 2019. Если вы используете другую версию Visual Studio, она может выглядеть иначе.

Перед началом работы

  • Для работы с этим руководством необходимо использовать Visual Studio Community (или более позднюю версию) либо одну из других версий Visual Studio на компьютере с Windows. Чтобы скачать, см. статью "Получить средства".
  • Чтобы продолжить работу, требуются общие знания о C++/CX и XAML, а также представление об основных понятиях, описанных в статье Общие сведения об XAML.
  • Для выполнения этой процедуры следует использовать в Visual Studio макет окна по умолчанию. Чтобы сбросить макет по умолчанию, в строке меню выберите "Макет окна>сброса окна".

Сравнение классических приложений C++ с приложениями UWP

Если у вас есть опыт создания классических приложений для Windows на C++, значит, некоторые аспекты создания приложений для UWP вам, вероятно, покажутся хорошо знакомыми, а другие потребуют изучения.

Что такое же?

  • Вы можете использовать STL, CRT (за некоторыми исключениями) и любую другую библиотеку C++, если код вызывает только функции Windows, которые доступны из среды выполнения Windows.

  • Если вы привыкли работать с областями визуальных конструкторов, можно использовать конструктор, встроенный в Microsoft Visual Studio, или использовать полнофункциональное приложение Blend для Visual Studio. Если вы обычно пишете код для пользовательского интерфейса вручную, значит, вы точно так же можете писать код XAML.

  • Вы по-прежнему создаете приложения, использующие типы операционной системы Windows и собственные пользовательские типы.

  • Вы по-прежнему используете отладчик Visual Studio, профилировщик и другие средства разработки.

  • Вы по-прежнему создаете приложения, скомпилированные в машинный код компилятором Visual C++. Выполнение приложений UWP на C++/CX не поддерживается в управляемой среде выполнения.

Новые возможности

  • Принципы разработки приложений UWP существенно отличаются от принципов разработки классических приложений. Границы окна, метки, диалоговые окна и т. д., выделены без выделения. В первую очередь содержимое. При создании приложений UWP этим принципам необходимо следовать с самого начала стадии планирования.

  • Вы используете XAML для определения всего пользовательского интерфейса. Разделение между пользовательским интерфейсом и основной логикой в приложении UWP намного более очевидно, чем в приложениях MFC или Win32. Другие пользователи могут работать с внешним видом пользовательского интерфейса в XAML-файле при работе с поведением в файле кода.

  • В первую очередь вы программируетсяе для нового, простого для навигации, объектно-ориентированного API, среда выполнения Windows, хотя на устройствах Windows Win32 по-прежнему доступно для некоторых функций.

  • Для использования и создания объектов среда выполнения Windows используется C++/CX. C++/CX включает обработку исключений C++, делегатов, событий и автоматическое подсчет ссылок динамически созданных объектов. При использовании C++/CX сведения о базовой архитектуре COM и Windows скрыты из кода приложения. Дополнительные сведения см. в справочнике по языку C++/CX.

  • Приложение компилируется в пакет, который также содержит метаданные о типах, содержащихся в приложении, ресурсах, которые он использует, и возможностях, необходимых для него (доступ к файлам, доступ к Интернету, доступ к камере и т. д.).

  • В Microsoft Store и Windows Phone Store приложение проходит сертификацию для подтверждения его надежности, после чего оно становится доступным для миллионов потенциальных клиентов.

Приложение Hello World на C++/CX для Store

Наше первое приложение — это "Hello World", демонстрирующее некоторые основные функции интерактивности, макета и стилей. Мы создадим приложение из шаблона проекта универсального приложения Windows. Если вы разработали приложения для Windows 8.1 и Windows Телефон 8.1 раньше, вы можете помнить, что вам пришлось иметь три проекта в Visual Studio, один для приложения Windows, один для телефонного приложения и другой с общим кодом. Благодаря универсальной платформе Windows (UWP) в Windows можно создать всего один проект, который работает на всех устройствах, в том числе на компьютерах и ноутбуках под управлением Windows, таких устройствах, как планшеты, мобильные телефоны, устройства виртуальной реальности и т. д.

Начнем с основных принципов:

  • Создание проекта универсального приложения для Windows в Visual Studio.

  • Как понять созданные проекты и файлы.

  • Как понять расширения в расширениях компонентов Visual C++ (C++/CX) и когда их следует использовать.

Сначала создайте решение в Visual Studio

  1. В Visual Studio в строке меню последовательно выберите Файл>Создать>Проект.

  2. В диалоговом окне Создание проекта выберите Пустое приложение (универсальное приложение для Windows — C++/CX). Если этот параметр не отображается, убедитесь, что вы установили средства разработки универсальных приложений для Windows. Дополнительные сведения см. в статье Подготовка.

C++/CX project templates in the Create a new project dialog box

  1. Нажмите кнопку Далее и введите имя для проекта. Мы будем называть его HelloWorld.

  2. Нажмите кнопку Создать.

Примечание.

Если вы используете Visual Studio впервые, может открыться диалоговое окно с запросом включить параметр Режим разработчика. Режим разработчика — это специальный параметр, включающий определенные функции, например разрешение на непосредственный запуск приложений, а не только через Store. Дополнительные сведения см. в разделе Подготовка устройства к разработке. Чтобы продолжить работу с этим руководством, выберите Режим разработчика, нажмите Да и закройте диалоговое окно.

Создаются файлы проекта.

Перед тем как продолжить работу, давайте изучим файлы решения.

Universal app solution with nodes collapsed

Сведения о файлах проекта

Каждый XAML-файл в папке проекта содержит соответствующий файл XAML.h и XAML.cpp-файл в той же папке и G.hpp-файл в папке "Созданные файлы", которая находится на диске, но не входит в проект. Файлы XAML изменяются для создания элементов пользовательского интерфейса и их подключения к источникам данных (DataBinding). Вы изменяете файлы H и CPP, чтобы добавить пользовательскую логику для обработчиков событий. Автоматически создаваемые файлы представляют преобразование разметки XAML в C++/CX. Не изменяйте эти файлы, но их можно изучить, чтобы лучше понять, как работает код программной части. В основном созданный файл содержит частичное определение класса для корневого элемента XAML. Это тот же класс вы изменяете в файлах *.xaml.h и .cpp. Созданные файлы объявляют дочерние элементы пользовательского интерфейса XAML как члены класса, чтобы можно было ссылаться на них в написанном коде. Во время сборки созданный код и код объединяются в полное определение класса, а затем компилируются.

Сначала рассмотрим файлы проекта.

  • App.xaml, App.xaml.h, App.xaml.cpp: представляет объект приложения, являющийся точкой входа приложения. App.xaml не содержит разметки пользовательского интерфейса для конкретной страницы, но вы можете добавлять стили пользовательского интерфейса и другие элементы, которые вы хотите получить доступ на любой странице. Файлы программной части содержат обработчики событий OnLaunched и OnSuspending . Как правило, вы добавляете пользовательский код здесь, чтобы инициализировать приложение при запуске и выполнении очистки при приостановке или завершении.
  • MainPage.xaml, MainPage.xaml.h, MainPage.xaml.cpp: содержит разметку XAML и код для страницы запуска по умолчанию в приложении. Она не поддерживает навигацию или встроенные элементы управления.
  • pch.h, pch.cpp: предварительно скомпилированные файл заголовка и файл, который включает его в проект. В pch.h можно включать любые заголовки, которые часто не изменяются и включаются в другие файлы в решении.
  • Package.appxmanifest: XML-файл, описывающий возможности устройства, необходимые приложению, а также сведения о версии приложения и другие метаданные. Чтобы открыть этот файл в конструкторе манифестов, дважды щелкните его.
  • HelloWorld_TemporaryKey.pfx: — ключ, разрешающий развертывание приложения на этом компьютере из Visual Studio.

Первый взгляд на код

Если вы изучите код в App.xaml.h, App.xaml.cpp в общем проекте, вы заметите, что это в основном код C++, который выглядит знакомым. Однако некоторые элементы синтаксиса могут быть не так знакомы, если вы не знакомы с среда выполнения Windows приложениями, или вы работали с C++/CLI. Ниже приведены наиболее распространенные нестандартные элементы синтаксиса, которые вы увидите в C++/CX:

Ссылочные классы

Почти все классы среда выполнения Windows, которые включают все типы элементов управления Windows API-XAML, страницы в приложении, сам класс App, все объекты устройства и сети, все типы контейнеров объявляются как класс ссылок. (Некоторые типы Windows представляют собой класс значений или структуру значений. Класс ссылок используется с любого языка. В C++/CX время существования этих типов регулируется с помощью автоматического подсчета ссылок (а не сборки мусора), чтобы не приходилось явно удалять эти объекты. Вы также можете создавать собственные классы ссылок.

namespace HelloWorld
{
   /// <summary>
   /// An empty page that can be used on its own or navigated to within a Frame.
   /// </summary>
   public ref class MainPage sealed
   {
      public:
      MainPage();
   };
}

Все типы среда выполнения Windows должны быть объявлены в пространстве имен и в отличие от ISO C++ сами типы имеют модификатор специальных возможностей. Общедоступный модификатор делает класс видимым для среда выполнения Windows компонентов за пределами пространства имен. Запечатанный ключевое слово означает, что класс не может служить базовым классом. Почти все классы ссылок запечатаны; Наследование классов широко не используется, так как JavaScript не понимает его.

ссылка на новые и ^ (шляпы)

Вы объявляете переменную класса ссылок с помощью оператора ^(hat) и создаете экземпляр объекта с ссылкой на новый ключевое слово. После этого вы получаете доступ к методам экземпляров объекта, используя оператор "->" почти так же, как указатель C++. Статические методы получают доступ к оператору :: так же, как в ISO C++.

В следующем коде мы используем полное имя, чтобы создать экземпляр объекта, и оператор "->", чтобы вызвать метод экземпляров.

Windows::UI::Xaml::Media::Imaging::BitmapImage^ bitmapImage =
     ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();

bitmapImage->SetSource(fileStream);

Как правило, в CPP-файле мы добавим директиву using namespace Windows::UI::Xaml::Media::Imaging и автоматический ключевое слово, чтобы тот же код выглядел следующим образом:

auto bitmapImage = ref new BitmapImage();
bitmapImage->SetSource(fileStream);

Свойства

Класс ссылок может иметь свойства, которые, как и в управляемых языках, являются специальными функциями-членами, которые отображаются как поля для использования кода.

public ref class SaveStateEventArgs sealed
{
   public:
   // Declare the property
   property Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ PageState
   {
      Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ get();
   }
   ...
};

   ...
   // consume the property like a public field
   void PhotoPage::SaveState(Object^ sender, Common::SaveStateEventArgs^ e)
   {    
      if (mruToken != nullptr && !mruToken->IsEmpty())
   {
      e->PageState->Insert("mruToken", mruToken);
   }
}

Делегаты

Как и в управляемых языках, делегат — это ссылочный тип, инкапсулирующий функцию с определенной подписью. Они чаще всего используются с событиями и обработчиками событий

// Delegate declaration (within namespace scope)
public delegate void LoadStateEventHandler(Platform::Object^ sender, LoadStateEventArgs^ e);

// Event declaration (class scope)
public ref class NavigationHelper sealed
{
   public:
   event LoadStateEventHandler^ LoadState;
};

// Create the event handler in consuming class
MainPage::MainPage()
{
   auto navigationHelper = ref new Common::NavigationHelper(this);
   navigationHelper->LoadState += ref new Common::LoadStateEventHandler(this, &MainPage::LoadState);
}

Добавление содержимого в приложение

Давайте добавим в приложение некоторое содержимое.

Шаг 1. Изменение начальной страницы

  1. В Обозреватель решений откройте MainPage.xaml.

  2. Создайте элементы управления для пользовательского интерфейса, добавив следующий КОД XAML в корневую сетку непосредственно перед закрывающим тегом. Он содержит StackPanel с текстовым блоком, который запрашивает имя пользователя, элемент TextBox, принимаюющий имя пользователя, кнопку и другой элемент TextBlock.

    <StackPanel x:Name="contentPanel" Margin="120,30,0,0">
        <TextBlock HorizontalAlignment="Left" Text="Hello World" FontSize="36"/>
        <TextBlock Text="What's your name?"/>
        <StackPanel x:Name="inputPanel" Orientation="Horizontal" Margin="0,20,0,20">
            <TextBox x:Name="nameInput" Width="300" HorizontalAlignment="Left"/>
            <Button x:Name="inputButton" Content="Say &quot;Hello&quot;"/>
        </StackPanel>
        <TextBlock x:Name="greetingOutput"/>
    </StackPanel>
    
  3. На этом этапе вы создали очень простое универсальное приложение Для Windows. Чтобы узнать, как выглядит приложение UWP, нажмите клавишу F5, чтобы создать, развернуть и запустить приложение в режиме отладки.

Откроется экран заставки по умолчанию. На нем будет присутствовать изображение (Assets\\SplashScreen.scale-100.png) и цвет фона, указанный в файле манифеста приложения. Сведения о настройке экрана-заставки см. в статье "Добавление экрана-заставки".

Когда экран-заставка исчезнет, появится приложение. На ней отображается главная страница приложения.

UWP app screen, with controls

Это не делает много , но поздравляем, вы создали свое первое приложение универсальная платформа Windows!

Чтобы остановить отладку и закрыть приложение, вернитесь в Visual Studio и нажмите клавиши SHIFT+F5.

Дополнительные сведения см. в разделе "Запуск приложения Магазина" из Visual Studio.

В приложении можно ввести текстовое поле, но нажатие кнопкине делает ничего. На последующих шагах создается обработчик событий для события click кнопки, в котором отображается персонализированное приветствие.

Шаг 2. Создание обработчика событий

  1. В файле MainPage.xaml в представлении XAML или конструктора нажмите кнопку "Сказать привет" в добавленном ранее стекеPanel.

  2. Откройте окно свойств, нажав клавишу F4, а затем нажмите кнопку "События" (Events button).

  3. Найдите событие Click. В текстовом поле введите имя функции, обрабатывающей событие Click . Для этого примера введите Button\_Click.

    Properties window, Events view

  4. Нажмите ВВОД. Метод обработчика событий создается в MainPage.xaml.cpp и открывается таким образом, чтобы можно было добавить код, выполняемый при возникновении события.

В то же время в MainPage.xaml код XAML для кнопки обновляется, чтобы объявить обработчик событий Click, как показано ниже:

<Button Content="Say &quot;Hello&quot;" Click="Button_Click"/>

Вы также можете просто добавить это в код xaml вручную, что может быть полезно, если конструктор не загружается. Если вы введете этот параметр вручную, введите "Click", а затем разрешите IntelliSense добавить новый обработчик событий. Таким образом Visual Studio создает необходимое объявление метода и заглушку.

Конструктор не загружается, если необработанное исключение возникает во время отрисовки. Отрисовка в конструкторе включает запуск версии страницы во время разработки. Это может быть полезно для отключения запуска пользовательского кода. Это можно сделать, изменив параметр в диалоговом окне "Сервис", "Параметры ". В конструкторе XAML не проверка выполните код проекта в конструкторе XAML (если это поддерживается).

  1. В файле MainPage.xaml.cpp добавьте следующий код в обработчик событий Button\_Click, который вы только что создали. В этом коде вы получаете имя пользователя из элемента управления nameInputTextBox и используете его, чтобы создать приветствие. greetingOutputTextBlock отображает результат.
void HelloWorld::MainPage::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    greetingOutput->Text = "Hello, " + nameInput->Text + "!";
}
  1. Задайте проект в качестве запуска, а затем нажмите клавишу F5, чтобы создать и запустить приложение. При вводе имени в текстовом поле и нажатии кнопки приложение отображает персонализированное приветствие.

App screen with message display

Шаг 3. Стиль начальной страницы

Выбор темы

Легко настроить внешний вид и удобство работы приложения. По умолчанию приложение использует ресурсы с легким стилем. Системные ресурсы также включают светлую тему. Давайте попробуем и посмотрим, как это выглядит.

Переключение на темную тему

  1. Откройте App.xaml.

  2. В открываемом теге Application измените свойство RequestedTheme и задайте для нее значение Dark:

    RequestedTheme="Dark"
    

    Ниже приведен полный тег приложения с темной темной темой:

    <Application
    x:Class="HelloWorld.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloWorld"
    RequestedTheme="Dark">
    
  3. Нажмите клавишу F5, чтобы создать и запустить ее. Обратите внимание, что он использует темную тему.

    App screen with dark theme

Какую тему следует использовать? Какой бы вы ни хотели. Вот наш пример: для приложений, которые в основном отображают изображения или видео, мы рекомендуем темную тему; для приложений, содержащих много текста, рекомендуется светлая тема. Если вы используете настраиваемую цветовую схему, используйте тему, которая лучше всего подходит для внешнего вида и чувства вашего приложения. В остальной части этого руководства мы используем тему Light в снимках экрана.

Примечание. Тема применяется после запуска приложения. Она не изменится, пока приложение работает.

Использование системных стилей

Прямо сейчас в приложении Windows текст очень мал и трудно читать. Давайте исправим эту проблему, применяя системный стиль.

Изменение стиля элемента

  1. В проекте Windows откройте MainPage.xaml.

  2. В представлении XAML или конструктора выберите "Что такое ваше имя?"TextBlock , добавленный ранее.

  3. В окне "Свойства" (F4) нажмите кнопку "Свойства" (Properties button) в правом верхнем углу.

  4. Разверните группу текста и задайте размер шрифта 18 пикселей.

  5. Разверните группу Miscellaneous и найдите свойство Style.

  6. Щелкните маркер свойства (зеленое поле справа от свойства Style), а затем в меню выберите System Resource>BaseTextBlockStyle.

    BaseTextBlockStyle — это ресурс, который определен в ResourceDictionary в <корневой папке>\Program Files\Windows Kits\10\Include\winrt\xaml\\design\generic.xaml.

    Properties window, Properties view

    В области конструктора XAML внешний вид текста изменяется. В редакторе XAML код XAML для TextBlock обновляется:

<TextBlock Text="What's your name?" Style="{ThemeResource BaseTextBlockStyle}"/>
  1. Повторите процесс, чтобы задать размер шрифта и назначить BaseTextBlockStyle элементу greetingOutputTextBlock .

    Совет. Хотя в этом элементе TextBlock нет текста, при наведении указателя мыши на область конструктора XAML голубой контур показывает его расположение, чтобы его можно было выбрать.  

    Теперь xaml выглядит следующим образом:

<StackPanel x:Name="contentPanel" Margin="120,30,0,0">
    <TextBlock Style="{ThemeResource BaseTextBlockStyle}" FontSize="18" Text="What's your name?"/>
    <StackPanel x:Name="inputPanel" Orientation="Horizontal" Margin="0,20,0,20">
        <TextBox x:Name="nameInput" Width="300" HorizontalAlignment="Left"/>
        <Button x:Name="inputButton" Content="Say &quot;Hello&quot;" Click="Button_Click"/>
    </StackPanel>
    <TextBlock Style="{ThemeResource BaseTextBlockStyle}" FontSize="18" x:Name="greetingOutput"/>
</StackPanel>
  1. Нажмите клавишу F5 , чтобы выполнить сборку и запустить приложение. Теперь выглядит следующим образом:

App screen with larger text

Шаг 4. Адаптация пользовательского интерфейса к разным размерам окна

Теперь мы адаптируем пользовательский интерфейс к разным размерам экрана, чтобы он выглядел хорошо на мобильных устройствах. Для этого добавьте VisualStateManager и задайте свойства, которые применяются для различных визуальных состояний.

Настройка макета пользовательского интерфейса

  1. В редакторе XAML добавьте этот блок XAML после открытия тега корневого элемента Grid .
<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState x:Name="wideState">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="641" />
            </VisualState.StateTriggers>
        </VisualState>
        <VisualState x:Name="narrowState">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="contentPanel.Margin" Value="20,30,0,0"/>
                <Setter Target="inputPanel.Orientation" Value="Vertical"/>
                <Setter Target="inputButton.Margin" Value="0,4,0,0"/>
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
  1. Отладка приложения на локальном компьютере. Обратите внимание, что пользовательский интерфейс выглядит так же, как и раньше, если окно не становится более узким, чем 641 пикселей, независимых от устройства (DIPs).
  2. Отладка приложения в эмуляторе мобильных устройств. Обратите внимание, что пользовательский интерфейс использует свойства, определенные в пользовательском narrowState интерфейсе, и отображается правильно на небольшом экране.

Mobile app screen with styled text

Если вы использовали VisualStateManager в предыдущих версиях XAML, вы можете заметить, что XAML здесь использует упрощенный синтаксис.

В VisualState с именем wideState AdaptiveTrigger с его свойством MinWindowWidth задано значение 641. Это означает, что состояние применяется только в том случае, если ширина окна не меньше 641 DIPs. Вы не определяете объекты Setter для этого состояния, поэтому он использует свойства макета, определенные в XAML для содержимого страницы.

Второй VisualState narrowStateимеет адаптивныйtrigger со свойством MinWindowWidth значение 0. Это состояние применяется, если ширина окна превышает 0, но менее 641 DIPs. (При 641 diPs wideState применяется.) В этом состоянии можно определить некоторые объекты Setter , чтобы изменить свойства макета элементов управления в пользовательском интерфейсе:

  • Левое поле contentPanel элемента уменьшается с 120 до 20.
  • Вы изменяете ориентацию элемента с горизонтальногоinputPanel на вертикальное.
  • В элемент добавляется верхняя часть 4 ДИП inputButton .

Итоги

Поздравляем, вы выполнили первое руководство! В нем описано, как добавить содержимое в универсальные приложения Windows, как добавить к ним интерактивность и как изменить их внешний вид.

Следующие шаги

Если у вас есть проект универсального приложения для Windows, ориентированный на Windows 8.1 и (или) Windows Phone 8.1, вы можете перенести его в Windows 10 или Windows 11. Для этого действия нет автоматического процесса, но его можно выполнить вручную. Начните с нового универсального проекта Windows, чтобы получить последнюю структуру системы проекта и файлы манифеста, скопировать файлы кода в структуру каталогов проекта, добавить элементы в проект и перезаписать XAML с помощью VisualStateManager в соответствии с инструкциями в этом разделе. Дополнительные сведения см. в статье Перенос проекта среда выполнения Windows 8 в проект универсальная платформа Windows (UWP) и перенос в универсальная платформа Windows (C++).

Если у вас есть существующий код C++, который требуется интегрировать с приложением UWP, например для создания пользовательского интерфейса UWP для существующего приложения, см. статью "Практическое руководство. Использование существующего кода C++ в универсальном проекте Windows".