Вчера, в 27-ю годовщину Delphi, Embarcadero выпустила демонстрацию WinUI 3, которую я представил на юбилейном вебинаре. Вот официальное объявление вместе с дополнительной технической информацией. Демо доступно в GetIt.
Table of Contents
Введение
Microsoft Windows App SDK (ранее известный как Project Reunion) включает новую собственную платформу пользовательского интерфейса под названием WinUI 3. WinUI 3 — это текущая платформа пользовательского интерфейса в архитектуре WinRT (Windows Runtime), и она доступна для упакованных приложений (через контейнеры APPX или MSIX). и неупакованные приложения с графическим интерфейсом (то есть обычные родные приложения Win32/Win64, например, созданные с помощью Delphi и RAD Studio. Эта ссылка на упакованные приложения не имеет ничего общего с пакетами Delphi.
Имейте также в виду, что Windows App SDK — это набор инструментов, отличный от одноименного Windows SDK, который уже давно доступен как часть установки Delphi.
Пример проекта SampleWinRT предназначен для того, чтобы показать, как создать простое приложение Delphi с графическим интерфейсом пользователя исключительно на основе среды Microsoft WinUI 3 (1.0), выпущенной в ноябре 2021 года. Предварительные версии WinUI3 требовали, чтобы приложение было развернуто как упакованное приложение Windows. но WinUI 3 (1.0) снимает это ограничение, что означает, что вы можете создать приложение WinUI 3 в Delphi как обычное приложение.
Дополнительную информацию о WinUI 3 можно найти здесь: https://docs.microsoft.com/en-us/windows/apps/winui/winui3
. Дополнительную информацию о Windows App SDK можно найти здесь: https://docs.microsoft.com . /en-us/окна/приложения/окна-приложение-SDK/
Демо поставляется с обновленными версиями модулей импорта WinRT Delphi RTL для поддержки версии 1.0 WinUI 3. Текущая версия Delphi 11 Alexandria поставляется с более старым набором таких же модулей импорта.
Предварительные требования: установщик среды выполнения приложений Windows и библиотека DLL загрузчика среды выполнения приложений Windows.
Чтобы создать и развернуть неупакованное приложение, вам потребуется несколько вещей, как подробно описано на странице https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/deploy-unpackaged-apps .
1. Во-первых, вам нужен установщик Windows App SDK , который вы можете получить по ссылке для скачивания на вышеупомянутой странице Microsoft или скачать его с https://aka.ms/windowsappsdk/1.0-stable/msix-installer. Это дает вам распространяемый файловый архив, в настоящее время называемый Microsoft.WindowsAppRuntime.Redist.1.0.0.zip, который содержит установщики для платформ x86 и x64 (оба называются WindowsAppRuntimeInstaller.exe) в папках с разумными именами.
Запуск установщика (с повышенными привилегиями) гарантирует, что у вас установлена среда выполнения приложений Windows — она находится в скрытых папках в C: Program FilesWindowsApps, например, версия x86 может быть установлена в C: Program FilesWindowsAppsMicrosoft.WindowsAppRuntime.1.0_0.319.455 .0_x86__8wekyb3d8bbwe.
2. Второе, что вам нужно, это DLL-загрузчик среды выполнения приложений Windows , Microsoft.WindowsAppRuntime.Bootstrap.dll. Этот файл получен из пакета NuGet Windows App SDK, в настоящее время Microsoft.WindowsAppSDK.1.0.0.nupkg, который доступен по адресу https://www.nuget.org/packages/Microsoft.WindowsAppSDK в папке runtimeswin10-x86native или среды выполненияwin10-x64native. Эта DLL должна быть размещена рядом с вашим исполняемым файлом, чтобы ее можно было найти при запуске приложения при вызове соответствующих API. DLL-загрузчик (или DLL-библиотека начальной загрузки) отвечает за поиск подходящей версии среды выполнения приложений Windows, которая реализует WinUI 3, на основе значений версии, переданных в его API запуска.
Примечание. Если вы использовали поддержку компонента Delphi TEdgeBrower, который является оберткой для другой функции SDK Window App, вы можете заметить сходство требований к среде выполнения (также необходимой конечным пользователям) и SDK с загружаемой распространяемой библиотекой DLL.
Скачивание демо
Демо-версия Delphi WinUI 3 доступна на сайте GetIt для клиентов RAD Studio 11 Alexandria. При его установке исходный код демонстрации и необходимых файлов библиотеки устанавливается вместе с файлом readme с содержимым, аналогичным этому сообщению в блоге. Это пакет GetIt:
Знакомство с демонстрацией
Демонстрационное приложение построено как консольное приложение не по необходимости, но для того, чтобы информация могла быть записана в окно консоли по мере выполнения приложения, предлагая также способ отображения сообщений об ошибках (например, отсутствующих зависимостях).
Примечание. WinUI 3 требует, чтобы вы запускали процесс без повышенных привилегий. Таким образом, демо проверяет это и завершается с простым сообщением, если обнаруживает повышенные привилегии. Без этой проверки WinUI 3 приводит к сбою приложения, казалось бы, некрасивым образом.
Предполагая, что мы передаем проверку привилегий, приложение вызывает API инициализации в DLL-загрузчике, MddBootstrapInitialize , и если это находит и запускает среду выполнения приложений Windows, приложение затем переходит к дальнейшей инициализации. Перед выходом приложение вызывает MddBootstrapShutdown для очистки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
uses WinRT; const // From includeWindowsAppSDK-VersionInfo.h in WinAppSDK NuGet package WINDOWSAPPSDK_RELEASE_MAJORMINOR = $00010000; WINDOWSAPPSDK_RUNTIME_VERSION_UINT64 = $0000013F01C70000; WINDOWSAPPSDK_RUNTIME_VERSION_DOTQUADSTRING = '0.319.455.0'; var PackageVersion: PACKAGE_VERSION; ... PackageVersion.Version := WINDOWSAPPSDK_RUNTIME_VERSION_UINT64; var HR := MddBootstrapInitialize(WINDOWSAPPSDK_RELEASE_MAJORMINOR, nil, PackageVersion); if Succeeded(HR) <strong>then try Main; WriteLn('Press Enter (again) to continue'); Readln; finally MddBootstrapShutdown; |
Как видите, версия пакета SDK и версия пакета среды выполнения заимствованы из файла заголовка (.h), расположенного в пакете NuGet SDK Windows App.
В Main мы вызываем статический метод Start объекта приложения WinUI 3 — см. https:// docs.microsoft.com/en-us/windows/winui/api/microsoft.ui.xaml.application.start . Это требует обратного вызова, который будет запущен при инициализации приложения, что позволит нам настроить все по своему усмотрению. К счастью, обратные вызовы WinRT (включая обратные вызовы WinUI 3) имеют ту же реализацию, что и анонимный метод Delphi, поэтому мы используем анонимный метод для настройки обработчика событий OnLaunched нашего приложения.
В WinUI 3 OnLaunched на самом деле не является обработчиком событий. Вместо этого OnLaunched — https://docs.microsoft.com/en-us/windows/winui/api/microsoft.ui.xaml.application.onlaunched — это метод, который мы должны переопределить в классе, наследующемся от WinUI. Класс приложения. Как нам справиться с этим требованием наследования от класса WinRT из Delphi?
WinUI помогает нам, предоставляя механизм, который мы можем использовать. В таком случае наследование от класса WinUI 3 включает 3 объекта:
1) Внутренний объект, дающий базовую реализацию, предоставляемую WinUI, в данном случае базовую реализацию приложения. Этот внутренний объект будет реализовывать интерфейс, который определяет методы, для которых мы будем предоставлять реализации; IApplicationOverrides в этом случае.
2) Внешний объект (иногда называемый базовым объектом), который обеспечивает пользовательскую реализацию рассматриваемого метода (методов). Этот внешний объект, который мы предоставим, также реализует IApplicationOverrides .
3) Объект-оболочка, который объединяет внутренний и внешний объекты и предоставляется WinUI.
Вот код из Main :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
var AppInner: IInspectable; var AppOuter: IApplicationOverrides; var AppWrapper: IApplication; // In this code block we use an anonymous procedure (which Delphi implements as an // interface with an Invoke method) that matches the layout of the callback interface type TCallbackProc = reference to procedure (p: IApplicationInitializationCallbackParams) safecall; procedure Main; begin // Here we define an anonymous method and cast it to the matching WinUI interface type var CallbackProc: TCallbackProc := procedure (p: IApplicationInitializationCallbackParams) safecall begin // First we create our derived class AppOuter := TDerivedApp.Create as IApplicationOverrides; // Then we get the IApplicationFactory... var Factory := TApplication.Factory; // ... and use it to get an IApplication wrapper, AppWrapper, // and an IApplicationOverrides inner as well AppWrapper := Factory.CreateInstance(AppOuter, AppInner); // We store the inner object in the outer one so // we can call the base functionality when needed AppOuter.Inner := AppInner as IApplicationOverrides; end; var AppInitCallback := ApplicationInitializationCallback(CallbackProc); TApplication.Start(AppInitCallback); end; |
Код настройки приложения из этого класса:
1 2 3 4 5 6 7 8 9 10 |
type TDerivedApp = class(TInspectableObject, IApplicationOverrides) private FInner: IApplicationOverrides; public // IApplicationOverrides methods procedure OnLaunched(args: ILaunchActivatedEventArgs); safecall; ... property Inner: IApplicationOverrides read FInner write FInner; end; |
Затем метод OnLaunched может выполнить всю необходимую настройку приложения. В этом случае мы создаем и настраиваем окно — https://docs.microsoft.com/en-us/windows/winui/api/microsoft.ui.xaml.window и заполняем его некоторыми элементами управления, создавая следующий пользовательский интерфейс:
Посмотрите в коде все подробности того, что происходит, но вкратце:
- Мы создаем элемент управления StackPanel и помещаем его в окно, затем создается кнопка с обработчиком события Click и добавляется в StackPanel .
- Затем мы используем некоторый XAML для создания еще одного StackPanel и дочернего элемента управления кнопки, снова с обработчиком событий Click, добавляя StackPanel в окно. Это дает нам 2 подхода для достижения одной и той же цели.
- Наконец, еще немного XAML используется для создания Grid и внутри него TextBlock , к которому затем добавляется пара обработчиков событий для OnPointerEntered и OnPointerExited .
- В конечном итоге мы получаем окно с парой кнопок и текстовым блоком. На кнопки можно нажимать, чтобы изменить их заголовок, а текстовый блок меняет цвет, когда вы перемещаете мышь в него и из него.
Обратите внимание, что для динамически создаваемых элементов управления пользовательского интерфейса (таких как первая кнопка) обработчики событий могут быть связаны напрямую, а когда элементы управления создаются с загрузкой конфигурации XAML, код должен найти соответствующий объект, чтобы связать с ним обработчик событий.
Примечание. В отличие от C# и C++ языковая проекция для Delphi в настоящее время не включает все различные интерфейсы, реализованные объектами WinRT и WinUI 3, в унифицированные прокси-классы, поэтому над интерфейсом ведется гораздо больше работы, чем в других местах.
Что дальше
Эта демонстрация использования Win UI 3 в упакованном или неупакованном приложении Delphi 11 в первую очередь предназначена для всех, кто хочет поэкспериментировать с этой новой технологией пользовательского интерфейса с точки зрения Delphi. Как Embarcadero, мы следим за развитием WinUI 3 и планируем, как поддерживать его в будущем. Microsoft объявила о будущей поддержке размещения элементов управления WinUI 3 в традиционном дескрипторе формы Windows (то есть в приложении VCL или FMX) через XAML Islands для Win UI 3 — функция, ожидаемая в конце 2022 года, поэтому нам еще рано обсуждать план более плавной интеграции. Следите за обновлениями.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition