Поделиться через


Создайте "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 Phone 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 в диалоговом окне

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

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

Примечание.

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

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

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

Решение для универсального приложения со свернутыми узлами

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

Каждый XAML-файл в папке проекта содержит соответствующий файл XAML.h и .xaml.cpp файл в той же папке, а файл G.hpp и 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) и создаете экземпляр объекта с помощью нового ключевого слова ref. После этого вы получаете доступ к методам экземпляров объекта, используя оператор "->" почти так же, как указатель 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, чтобы тот же код выглядел следующим образом:

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 с элементами управления

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

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

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

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

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

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

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

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

    окно свойств, представление событий

  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, который вы только что создали. В этом коде вы получаете имя пользователя из элемента управления nameInput TextBox и используете его, чтобы создать приветствие. greetingOutput TextBlock отображает результат.
void HelloWorld::MainPage::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    greetingOutput->Text = "Hello, " + nameInput->Text + "!";
}
  1. Задайте проект в качестве запуска, а затем нажмите клавишу F5, чтобы создать и запустить приложение. При вводе имени в текстовом поле и нажатии кнопки приложение отображает персонализированное приветствие.

Экран приложения с отображением сообщения

Шаг 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, чтобы создать и запустить ее. Обратите внимание, что он использует темную тему.

    Экран приложения с темной темной темой

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

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

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

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

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

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

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

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

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

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

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

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

    окно свойств, представление свойств

    В области конструктора 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 , чтобы выполнить сборку и запустить приложение. Теперь выглядит следующим образом:

Экран приложения с большим текстом

Шаг 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 интерфейсе, и отображается правильно на небольшом экране.

Экран мобильного приложения со стилем текста

Если вы использовали 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".