Размещение настраиваемого элемента управления WinRT XAML в классическом приложении C++ (Win32)
Внимание
В этом разделе используются или упоминаются типы из репозитория CommunityToolkit/Microsoft.Toolkit.Win32 GitHub. Дополнительные сведения о поддержке XAML Islands см . в уведомлении о xaml Islands в этом репозитории.
В этой статье описано, как разместить настраиваемый элемент управления WinRT XAML в новом классическом приложении C++ с помощью API размещения WinRT XAML. Если у вас есть проект классического приложения C++, вы можете адаптировать эти шаги и примеры кода.
Чтобы разместить настраиваемый элемент управления WinRT XAML, в рамках этого пошагового руководства вы создадите следующие проекты и компоненты:
Проект классического приложения для Windows. Этот проект реализует собственное классическое приложение C++. Вы добавите код в этот проект, использующий API размещения WinRT XAML для размещения настраиваемого элемента управления WinRT XAML.
Проект приложения UWP (C++/WinRT). Этот проект реализует настраиваемый элемент управления WinRT XAML. Он также реализует корневой поставщик метаданных для загрузки метаданных настраиваемых типов WinRT XAML в проекте.
Требования
- Visual Studio 2019 версии 16.4.3 и более поздних версий.
- Windows 10 версии 1903 SDK (версия 10.0.18362) или более поздней версии.
- Расширение Visual Studio (VSIX) C++/WinRT, установленное с помощью Visual Studio. C++/WinRT — это полностью стандартная проекция языка C++17 для API среды выполнения Windows (WinRT), реализованная как библиотека на основе файлов заголовков и предназначенная для предоставления вам первоклассного доступа к современным интерфейсам API Windows. Дополнительные сведения см. в статье C++/WinRT.
Создание проекта классического приложения
В Visual Studio создайте проект классического приложения для Windows с именем MyDesktopWin32App. Доступ к шаблону этого проекта можно получить, используя фильтры для проекта Рабочий стол, C++ и Windows.
В обозревателе решений щелкните правой кнопкой мыши узел решения, выберите команду Изменить целевую платформу решения, выберите 10.0.18362.0 или более позднюю версию пакета SDK, а затем нажмите кнопку ОК.
Установите пакет NuGet Microsoft.Windows.CppWinRT, чтобы включить поддержку C++/WinRT в проекте.
- Щелкните правой кнопкой мыши проект MyDesktopWin32App в обозревателе решений и выберите пункт Manage NuGet Packages (Управление пакетами NuGet).
- Перейдите на вкладку Обзор, найдите пакет Microsoft.Windows.CppWinRT и установите последнюю версию этого пакета.
В окне Manage NuGet Packages (Управление пакетами NuGet) установите следующие дополнительные пакеты NuGet:
- Microsoft.Toolkit.Win32.UI.SDK (последняя стабильная версия). Этот пакет включает несколько ресурсов сборки и времени выполнения, которые позволяют XAML Islands работать в приложении.
- Microsoft.Toolkit.Win32.UI.XamlApplication (последняя стабильная версия). Пакет определяет класс Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication, который будет использоваться позднее в рамках этого пошагового руководства.
- Microsoft.VCRTForwarders.140.
Добавьте ссылку на метаданные среды выполнения Windows:
- В Обозревателе решений щелкните правой кнопкой мыши узел Ссылки проекта и выберите команду Добавить ссылку.
- Нажмите кнопку Обзор в нижней части страницы и перейдите к папке UnionMetadata по пути установки пакета SDK. По умолчанию пакет SDK будет установлен в
C:\Program Files (x86)\Windows Kits\10\UnionMetadata
. - Затем выберите папку с именем, которое соответствует целевой версии Windows (например, 10.0.18362.0). В этой папке выберите файл
Windows.winmd
. - Нажмите кнопку ОК, чтобы закрыть диалоговое окно Добавление ссылки.
Запустите сборку решения и убедитесь, что она проходит успешно.
Создание проекта приложения UWP
Теперь добавьте проект приложения UWP (C++/WinRT) в решение и внесите некоторые изменения в конфигурацию этого проекта. Далее в этом пошаговом руководстве вы добавите код в этот проект, чтобы внедрить настраиваемый элемент управления WinRT XAML и определить экземпляр класса Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication.
В обозревателе решений, щелкните правой кнопкой мыши по узлу решения и выберите Добавить ->Новый проект.
Добавьте в решение проект пустого приложения (C++/WinRT). Присвойте проекту имя MyUWPApp и убедитесь, что в качестве целевой и минимальной версии используется Windows 10 версии 1903 или более поздней.
Установите пакет NuGet Microsoft.Toolkit.Win32.UI.XamlApplication в проект MyUWPApp. Пакет определяет класс Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication, который будет использоваться позднее в рамках этого пошагового руководства.
- Щелкните правой кнопкой мыши проект MyUWPApp и выберите пункт Manage NuGet Packages (Управление пакетами NuGet).
- Перейдите на вкладку Обзор, найдите пакет Microsoft.Toolkit.Win32.UI.XamlApplication и установите последнюю стабильную версию этого пакета.
Щелкните правой кнопкой мыши узел MyUWPApp и выберите пункт Свойства. На странице Общие свойства ->C++/WinRT, установите значение для свойства Уровень детализации значение нормальная, затем нажмите Применить. По завершении страница свойств должна выглядеть следующим образом:
На странице Свойства конфигурации ->Общие окна свойств, задайте Тип конфигурации для динамической библиотеки (.dll), затем нажмите ОК, чтобы закрыть окно свойств.
Добавьте исполняемый файл заполнителя в проект MyUWPApp. Этот исполняемый файл заполнителя необходим для создания необходимых файлов проекта и правильной сборки проекта в Visual Studio.
В обозревателе решений, щелкните правой кнопкой мыши по узлу проекта MyUWPApp и выберите Добавить ->Новый элемент.
В диалоговом окне Добавление нового элемента выберите раздел Служебная программа на панели слева, а затем щелкните Текстовый файл (.txt). Введите имя placeholder.exe и нажмите кнопку Добавить.
В обозревателе решений выберите файл placeholder.exe. В окне Свойства убедитесь, что для свойства Содержимое установлено значение True.
В обозревателе решений щелкните правой кнопкой мыши файл Package.appxmanifest в проекте MyUWPApp, выберите команду Открыть с помощью, а затем Редактор (текстовый) XML и нажмите кнопку ОК.
Найдите элемент <Приложение> и измените значение для атрибута Исполняемый файл на
placeholder.exe
. По завершении элемент <Приложение> должен выглядеть примерно так:<Application Id="App" Executable="placeholder.exe" EntryPoint="MyUWPApp.App"> <uap:VisualElements DisplayName="MyUWPApp" Description="Project for a single page C++/WinRT Universal Windows Platform (UWP) app with no predefined layout" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" BackgroundColor="transparent"> <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"> </uap:DefaultTile> <uap:SplashScreen Image="Assets\SplashScreen.png" /> </uap:VisualElements> </Application>
Сохраните и закройте файл Package.appxmanifest.
В обозревателе решений щелкните правой кнопкой мыши узел MyUWPApp и выберите команду Выгрузить проект.
Щелкните правой кнопкой мыши узел MyUWPApp и выберите MyUWPApp.vcxproj.
Найдите элемент
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
и замените его ниже указанным XML-кодом. Этот XML-код добавляет несколько новых свойств непосредственно перед элементом.<PropertyGroup Label="Globals"> <WindowsAppContainer>true</WindowsAppContainer> <AppxGeneratePriEnabled>true</AppxGeneratePriEnabled> <ProjectPriIndexName>App</ProjectPriIndexName> <AppxPackage>true</AppxPackage> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
Сохраните и закройте файл проекта.
В обозревателе решений щелкните правой кнопкой мыши узел MyUWPApp и выберите команду Перезагрузить проект.
Настроить решение
В этом разделе вы обновите решение, содержащее все проекты, чтобы настроить зависимости проекта и свойства сборки, необходимые для правильной сборки проектов.
В обозревателе решений щелкните правой кнопкой мыши узел решения и добавьте новый XML-файл с именем Solution.props.
Добавьте следующий XML-код в файл Solution.props.
<?xml version="1.0" encoding="utf-8"?> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <IntDir>$(SolutionDir)\obj\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</IntDir> <OutDir>$(SolutionDir)\bin\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</OutDir> <GeneratedFilesDir>$(IntDir)Generated Files\</GeneratedFilesDir> </PropertyGroup> </Project>
В меню Просмотр, щелкните мышью подиспетчеру свойств (в зависимости от конфигурации этот параметр может находится в разделе Просмотр ->Другие Windows).
В окне диспетчера свойств щелкните правой кнопкой мыши MyDesktopWin32App и выберите команду Добавить существующую страницу свойств. Перейдите в только что добавленный файл Solution.props и щелкните Открыть.
Повторите предыдущий шаг, чтобы добавить файл Solution.props в проект MyUWPApp в окне диспетчера свойств.
Закройте окно диспетчера свойств.
Убедитесь, что изменения на странице свойств сохранены правильно. В обозревателе решений щелкните правой кнопкой мыши проект MyDesktopWin32App и выберите пункт Свойства. Последовательно выберите Свойства конфигурации ->Общие и подтвердите, что свойстваВыходной каталог и Промежуточный каталог имеют значения, добавленные вами в файл Solution.props. Вы также можете проверить значения для проекта MyUWPApp.
В обозревателе решений щелкните правой кнопкой мыши узел решения и выберите пункт Зависимости проектов. В раскрывающемся списке Проекты убедитесь, что выбран MyDesktopWin32App, и выберите MyUWPApp в списке Depends On (Зависит от).
Щелкните OK.
Добавление кода в проект приложения UWP
Теперь вы готовы добавить код в проект MyUWPApp, чтобы выполнить следующие задачи:
- Реализация пользовательского элемента управления WinRT XAML Далее в этом пошаговом руководстве вы добавите код, который размещает этот элемент управления в проекте MyDesktopWin32App.
- Определите тип, производный от класса Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication в наборе средств сообщества Windows.
Определение пользовательского элемента управления WinRT XAML
В обозревателе решений, щелкните правой кнопкой мыши файл MyUWPApp выберите Добавить ->Новый элемент. Выберите узел Visual C++ в левой области, затем Blank User Control (C++/WinRT) (Пустой пользовательский элемент управления (C++/WinRT)), назовите его MyUserControl и щелкните Добавить.
В редакторе XAML замените содержимое файла MyUserControl.XAML на следующий XAML-код, а затем сохраните файл:
<UserControl x:Class="MyUWPApp.MyUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyUWPApp" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <StackPanel HorizontalAlignment="Center" Spacing="10" Padding="20" VerticalAlignment="Center"> <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="Hello from XAML Islands" FontSize="30" /> <TextBlock HorizontalAlignment="Center" Margin="15" TextWrapping="Wrap" Text="😍❤💋🌹🎉😎�🐱👤" FontSize="16" /> <Button HorizontalAlignment="Center" x:Name="Button" Click="ClickHandler">Click Me</Button> </StackPanel> </UserControl>
Определение класса XamlApplication
Затем замените класс App по умолчанию в проекте MyUWPApp производным от класса Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication, предоставляемым в наборе средств сообщества Windows. Этот класс поддерживает интерфейс IXamlMetadataProvider, который позволяет приложению обнаруживать и загружать метаданные для настраиваемых элементов управления WinRT XAML в сборках в текущем каталоге приложения во время выполнения. Этот класс также инициализирует платформу WinRT XAML для текущего потока. Позднее в рамках этого пошагового руководства вы обновите проект классического приложения, чтобы создать экзепляр этого класса.
Примечание.
Каждое решение, использующее XAML Islands, может содержать только один проект, определяющий объект XamlApplication
. Все пользовательские элементы управления WinRT XAML в приложении используют один и тот же объект XamlApplication
.
В обозревателе решений щелкните правой кнопкой мыши файл MainPage.xaml в проекте MyUWPApp. Выберите команду Убрать, а затем — команду Удалить, чтобы удалить этот файл из проекта без возможности восстановления.
В проекте MyUWPApp разверните файл App.xaml.
Замените содержимое файлов App.xaml, App.cpp, App.h и App.idl кодом, указанным ниже.
App.xaml:
<Toolkit:XamlApplication x:Class="MyUWPApp.App" xmlns:Toolkit="using:Microsoft.Toolkit.Win32.UI.XamlHost" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyUWPApp"> </Toolkit:XamlApplication>
App.idl:
namespace MyUWPApp { [default_interface] runtimeclass App : Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication { App(); } }
App.h:
#pragma once #include "App.g.h" #include "App.base.h" namespace winrt::MyUWPApp::implementation { class App : public AppT2<App> { public: App(); ~App(); }; } namespace winrt::MyUWPApp::factory_implementation { class App : public AppT<App, implementation::App> { }; }
App.cpp:
#include "pch.h" #include "App.h" #include "App.g.cpp" using namespace winrt; using namespace Windows::UI::Xaml; namespace winrt::MyUWPApp::implementation { App::App() { Initialize(); AddRef(); m_inner.as<::IUnknown>()->Release(); } App::~App() { Close(); } }
Примечание.
#include "App.g.cpp"
Инструкция необходима, когда для свойства Оптимизирован на странице Общие свойства проекта ->C++/WinRT в свойствах проекта установлено значение Да. Это значение по умолчанию для новых проектов C++/WinRT. Дополнительные сведения о влиянии свойства Оптимизирован см. в этом разделе.
Добавьте новый файл заголовка в проект MyUWPApp с именем app.base.h.
Добавьте следующий код в файл app.base.h, сохраните файл и закройте его.
#pragma once namespace winrt::MyUWPApp::implementation { template <typename D, typename... I> struct App_baseWithProvider : public App_base<D, ::winrt::Windows::UI::Xaml::Markup::IXamlMetadataProvider> { using IXamlType = ::winrt::Windows::UI::Xaml::Markup::IXamlType; IXamlType GetXamlType(::winrt::Windows::UI::Xaml::Interop::TypeName const& type) { return _appProvider.GetXamlType(type); } IXamlType GetXamlType(::winrt::hstring const& fullName) { return _appProvider.GetXamlType(fullName); } ::winrt::com_array<::winrt::Windows::UI::Xaml::Markup::XmlnsDefinition> GetXmlnsDefinitions() { return _appProvider.GetXmlnsDefinitions(); } private: bool _contentLoaded{ false }; winrt::MyUWPApp::XamlMetaDataProvider _appProvider; }; template <typename D, typename... I> using AppT2 = App_baseWithProvider<D, I...>; }
Запустите сборку решения и убедитесь, что она проходит успешно.
Настройка проекта классического приложения для использования типов настраиваемых элементов управления
Прежде чем приложение MyDesktopWin32App разместит настраиваемый элемент управления WinRT XAML в XAML Island, в приложении необходимо настроить использование типов настраиваемых элементов управления из проекта MyUWPApp. Это можно сделать двумя способами, и после ознакомления с этим пошаговым руководством вы можете выбрать любой из них.
Вариант 1. Упаковка приложения с помощью MSIX
Вы можете упаковать приложение в пакет MSIX для развертывания. MSIX — это современная технология упаковки приложений для Windows. В ее основе лежат технологии установки MSI, APPX, App-V и ClickOnce.
Добавьте новый проект упаковки приложений Windows в свое решение. При создании проекта назовите его MyDesktopWin32Project и выберите Windows 10 версии 1903 (10.0; сборка 18362) в качестве целевой и минимальной версии.
В проекте упаковки щелкните правой кнопкой мыши узел Приложения и выберите команду Добавить ссылку. В списке проектов установите флажок рядом с проектом MyDesktopWin32App и нажмите кнопку ОК.
Сведения о распространении и развертывании пакета см. в статье Управление развертыванием MSIX.
Примечание.
Если вы решили не упаковывать приложение в пакет MSIX для развертывания, на компьютерах с запущенными приложениями должна быть установлена среда выполнения Visual C++.
Вариант 2. Создание манифеста приложения
Можно добавить манифест в приложение.
Щелкните правой кнопкой мыши по проекту MyDesktopWin32App и выберите Добавить ->Новый элемент.
В диалоговом окне Добавление нового элемента щелкните Web (Веб) в левой области и выберите XML-файл (.xml).
Назовите новый файл app.manifest и щелкните Добавить.
Замените содержимое нового файла XML-кодом, указанным ниже. Этот XML-код регистрирует типы настраиваемых элементов управления в проекте MyUWPApp.
<?xml version="1.0" encoding="utf-8"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0"> <asmv3:file name="MyUWPApp.dll"> <activatableClass name="MyUWPApp.App" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1" /> <activatableClass name="MyUWPApp.XamlMetadataProvider" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1" /> <activatableClass name="MyUWPApp.MyUserControl" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1" /> </asmv3:file> </assembly>
Настройка дополнительных свойств проекта классического приложения
Далее обновите проект MyDesktopWin32App, чтобы определить макрос для дополнительных каталогов включаемых файлов и настроить дополнительные свойства.
В обозревателе решений щелкните правой кнопкой мыши проект MyDesktopWin32App и выберите команду Выгрузить проект.
Щелкните правой кнопкой мыши MyDesktopWin32App (Unloaded) (MyDesktopWin32App (Выгружен)) и выберите команду Edit MyDesktopWin32App.vcxproj (Изменить MyDesktopWin32App.vcxproj).
Добавьте XML-код, указанный ниже, напрямую перед закрывающим тегом
</Project>
в конце файла. Затем сохраните и закройте файл.<!-- Configure these for your UWP project --> <PropertyGroup> <AppProjectName>MyUWPApp</AppProjectName> </PropertyGroup> <PropertyGroup> <AppIncludeDirectories>$(SolutionDir)\obj\$(Platform)\$(Configuration)\$(AppProjectName)\;$(SolutionDir)\obj\$(Platform)\$(Configuration)\$(AppProjectName)\Generated Files\;</AppIncludeDirectories> </PropertyGroup> <ItemGroup> <ProjectReference Include="..\$(AppProjectName)\$(AppProjectName).vcxproj" /> </ItemGroup> <!-- End Section-->
В обозревателе решений щелкните правой кнопкой мыши MyDesktopWin32App (unloaded) (MyDesktopWin32App (выгружен)) и выберите команду Перезагрузить проект.
Щелкните правой кнопкой мыши по проекту MyDesktopWin32App, выберите Свойства, и разверните Инструмент манифеста ->Ввод и вывод на левой панели. Задайте для свойства Поддержка DPI значение Поддержка высокого DPI по мониторам. Если это свойство не задано, может возникнуть ошибка конфигурации манифеста в некоторых сценариях с высоким количеством точек на дюйм.
Нажмите кнопку ОК, чтобы закрыть диалоговое окно Страницы свойств.
Размещение настраиваемого элемента управления WinRT XAML в проекте классического приложения
Теперь можно добавить код в проект MyDesktopWin32App для размещения настраиваемого элемента управления WinRT XAML, определенного ранее в проекте MyUWPApp.
В проекте MyDesktopWin32App откройте файл framework.h и закомментируйте строку кода, указанную ниже. По завершении сохраните файл.
#define WIN32_LEAN_AND_MEAN
Откройте файл MyDesktopWin32App.h и замените содержимое этого файла кодом, указанным ниже, чтобы создать ссылки на необходимые заголовочные файлы C++/WinRT. По завершении сохраните файл.
#pragma once #include "resource.h" #include <winrt/Windows.Foundation.Collections.h> #include <winrt/Windows.system.h> #include <winrt/windows.ui.xaml.hosting.h> #include <windows.ui.xaml.hosting.desktopwindowxamlsource.h> #include <winrt/windows.ui.xaml.controls.h> #include <winrt/Windows.ui.xaml.media.h> #include <winrt/Windows.UI.Core.h> #include <winrt/MyUWPApp.h> using namespace winrt; using namespace Windows::UI; using namespace Windows::UI::Composition; using namespace Windows::UI::Xaml::Hosting; using namespace Windows::Foundation::Numerics; using namespace Windows::UI::Xaml::Controls;
Откройте файл MyDesktopWin32App.cpp и добавьте следующий код в раздел
Global Variables:
:winrt::MyUWPApp::App hostApp{ nullptr }; winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource _desktopWindowXamlSource{ nullptr }; winrt::MyUWPApp::MyUserControl _myUserControl{ nullptr };
В том же файле добавьте следующий код в раздел
Forward declarations of functions included in this code module:
:void AdjustLayout(HWND);
В том же файле добавьте следующий код сразу после комментария
TODO: Place code here.
в функцииwWinMain
:// TODO: Place code here. winrt::init_apartment(winrt::apartment_type::single_threaded); hostApp = winrt::MyUWPApp::App{}; _desktopWindowXamlSource = winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource{};
В том же файле замените функцию
InitInstance
по умолчанию на следующий код:BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // Store instance handle in our global variable HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } // Begin XAML Islands walkthrough code. if (_desktopWindowXamlSource != nullptr) { auto interop = _desktopWindowXamlSource.as<IDesktopWindowXamlSourceNative>(); check_hresult(interop->AttachToWindow(hWnd)); HWND hWndXamlIsland = nullptr; interop->get_WindowHandle(&hWndXamlIsland); RECT windowRect; ::GetWindowRect(hWnd, &windowRect); ::SetWindowPos(hWndXamlIsland, NULL, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_SHOWWINDOW); _myUserControl = winrt::MyUWPApp::MyUserControl(); _desktopWindowXamlSource.Content(_myUserControl); } // End XAML Islands walkthrough code. ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; }
В том же файле добавьте следующую новую функцию в конец файла:
void AdjustLayout(HWND hWnd) { if (_desktopWindowXamlSource != nullptr) { auto interop = _desktopWindowXamlSource.as<IDesktopWindowXamlSourceNative>(); HWND xamlHostHwnd = NULL; check_hresult(interop->get_WindowHandle(&xamlHostHwnd)); RECT windowRect; ::GetWindowRect(hWnd, &windowRect); ::SetWindowPos(xamlHostHwnd, NULL, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_SHOWWINDOW); } }
В том же файле найдите функцию
WndProc
. Замените обработчикWM_DESTROY
по умолчанию в операторе switch на следующий код:case WM_DESTROY: PostQuitMessage(0); if (_desktopWindowXamlSource != nullptr) { _desktopWindowXamlSource.Close(); _desktopWindowXamlSource = nullptr; } break; case WM_SIZE: AdjustLayout(hWnd); break;
Сохраните файл.
Запустите сборку решения и убедитесь, что она проходит успешно.
Добавление элемента управления из библиотеки WinUI версии 2 в пользовательский элемент управления
В большинстве случаев элементы управления WinRT XAML выпущены в составе ОС Windows. Разработчики могут использовать их через Windows SDK. В качестве альтернативного варианта можно использовать библиотеку WinUI. Здесь обновленные версии элементов управления WinRT XAML из пакета Windows SDK распределены в пакете NuGet, который не связан с выпусками пакета Windows SDK. Эта библиотека также содержит новые элементы управления, которые не входят в состав пакета Windows SDK и платформы UWP по умолчанию.
В этом разделе показано, как добавить элемент управления WinRT XAML из библиотеки WinUI версии 2 в пользовательский элемент управления.
Примечание.
Сейчас XAML Islands поддерживают только размещение элементов управления из библиотеки WinUI версии 2. Поддержка размещения элементов управления из библиотеки WinUI 3 будет реализована в более позднем выпуске.
В проекте MyUWPApp установите последнюю предварительную или окончательную версию пакета NuGet Microsoft.UI.Xaml.
- Если ранее при прохождении этого пошагового руководства вы решили упаковать проект MyDesktopWin32App с помощью MSIX, то теперь можете установить предварительную или окончательную версию пакета NugGet Microsoft.UI.Xaml. Упакованные классические приложения могут использовать либо предварительную, либо окончательную версию этого пакета.
- Если вы решили не упаковывать проект MyDesktopWin32App, то теперь вам нужно установить предварительную версию пакета NuGet Microsoft.UI.Xaml. Неупакованные классические приложения должны использовать предварительную версию этого пакета.
В файле pch.h в этом проекте добавьте следующие инструкции
#include
и сохраните изменения. Эти инструкции предоставляют необходимый набор заголовков проекции из библиотеки WinUI в проекте. Этот шаг необходим для любого проекта C++/WinRT, использующего библиотеку WinUI. Дополнительные сведения см. в этой статье.#include "winrt/Microsoft.UI.Xaml.Automation.Peers.h" #include "winrt/Microsoft.UI.Xaml.Controls.Primitives.h" #include "winrt/Microsoft.UI.Xaml.Media.h" #include "winrt/Microsoft.UI.Xaml.XamlTypeInfo.h"
В файле App.xaml в том же проекте добавьте следующий дочерний элемент в элемент
<xaml:XamlApplication>
и сохраните изменения.<Application.Resources> <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" /> </Application.Resources>
После добавления этого элемента содержимое файла должно выглядеть следующим образом:
<Toolkit:XamlApplication x:Class="MyUWPApp.App" xmlns:Toolkit="using:Microsoft.Toolkit.Win32.UI.XamlHost" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyUWPApp"> <Application.Resources> <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/> </Application.Resources> </Toolkit:XamlApplication>
В том же проекте откройте файл MyUserControl.xaml и добавьте следующее объявление пространства имен в элемент
<UserControl>
.xmlns:winui="using:Microsoft.UI.Xaml.Controls"
В том же файле добавьте элемент
<winui:RatingControl />
в качестве дочернего элемента<StackPanel>
и сохраните изменения. Этот элемент добавляет экземпляр класса RatingControl из библиотеки WinUI. После добавления этого элемента<StackPanel>
должен выглядеть следующим образом.<StackPanel HorizontalAlignment="Center" Spacing="10" Padding="20" VerticalAlignment="Center"> <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="Hello from XAML Islands" FontSize="30" /> <TextBlock HorizontalAlignment="Center" Margin="15" TextWrapping="Wrap" Text="😍❤💋🌹🎉😎�🐱👤" FontSize="16" /> <Button HorizontalAlignment="Center" x:Name="Button" Click="ClickHandler">Click Me</Button> <winui:RatingControl /> </StackPanel>
Запустите сборку решения и убедитесь, что она проходит успешно.
Тестирование приложения
Запустите решение и убедитесь, что MyDesktopWin32App открывается в следующем окне:
Следующие шаги
Многим классическим приложениям, в которых используется XAML Islands, потребуется обрабатывать дополнительные сценарии, чтобы обеспечить бесперебойную работу пользовательского интерфейса. Например, в классических приложениях может потребоваться обрабатывать ввод с клавиатуры в XAML Islands, выполнять переход между XAML Islands и другими элементами пользовательского интерфейса, а также изменять макет.
Дополнительные сведения о работе с такими сценариями и связанные примеры кода см. в статье Расширенные сценарии использования XAML Islands в классических приложениях C++.
См. также
- Элементы управления WinRT XAML в классических приложениях (XAML Islands)
- Использование API размещения WinRT XAML в классическом приложении Win32
- Размещение стандартного элемента управления WinRT XAML в классическом приложении Win32
- Расширенные сценарии использования XAML Islands в классических приложениях Win32
- Примеры кода для XAML Islands
Windows developer