Применение Mica в классических приложениях Win32 для Windows 11
Mica — это непрозрачный материал, который включает тему пользователя и обои на рабочем столе для создания персонализированного внешнего вида. Когда пользователь перемещает окно по экрану, материал Mica динамически адаптируется для создания полнофункциональных визуализаций с помощью фонового рисунка под приложением. Кроме того, этот материал помогает пользователям сосредоточиться на текущей задаче, возвращаясь к нейтральному цвету, когда приложение неактивно.
В этой статье описывается, как применить Mica в качестве базового слоя приложения Win32, чтобы определить приоритеты приложения и видимости в области заголовка. Дополнительные сведения о настройке слоев приложений с помощью Mica см. в разделе Материал Mica.
Необходимые компоненты
Чтобы применить Mica к приложению Win32 для Windows 11, необходимо использовать Windows App SDK. Потребуется следующее:
- Установите последнюю версию расширения Visual Studio для Windows App SDK или пакета NuGet Microsoft.WindowsAppSDK. См. раздел Загружаемые файлы пакета Windows App SDK.
- Для неупакованных приложений найдите Windows App SDK, установите WinRT и установите соответствующий распространяемый компонент среды выполнения приложений Windows (Microsoft.WindowsAppRuntime.Redist). См . руководство по развертыванию пакета SDK для приложений, зависящих от платформы, с внешним расположением или распаковкой.
Использование Mica в приложениях Win32
Чтобы использовать Mica в приложении, используйте класс MicaController. Этот класс управляет отрисовкой материала фона системы, а также обработкой системной политики для материала Mica.
MicaController реагирует на системные светлые и темные темы по умолчанию. Чтобы переопределить это поведение, можно передать в MicaController следующие свойства:
Совет
Код в этом разделе взят из примера Windows App SDK Win32 Mica в GitHub. См. полный код в репозитории GitHub. В этих примерах используется C++/WinRT.
Чтобы включить Mica, вам потребуется ссылка на Windows App SDK, Compositor и DispatcherQueue.
В этом примере показано, как настроить неупакованное приложение:
- Инициализируйте WinRT.
- Создайте ссылку на WindowsAppSDK из неупакованного приложения.
- Дополнительные сведения см. в статье "Использование среды выполнения ПАКЕТА SDK для приложений Windows", упакованных с внешним расположением или распаковкой .
- Примеры кода см. в
WindowsAppSDKBootstrapperContext
в Utilities.h.
- Зарегистрируйте класс окна.
- Создание контроллера очереди диспетчера Mica
- Инициализируйте компоновщик WinRT.
Из WinMain.cpp
int __stdcall WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PSTR, _In_ int)
{
// Initialize WinRt Instance
winrt::init_apartment();
// Enable referencing the WindowsAppSDK from an unpackaged app.
Utilities::WindowsAppSDKBootstrapperContext sdkContext;
// Register Window class before making the window.
MicaWindow::RegisterWindowClass();
// Mica requires a compositor, which also requires a dispatcher queue.
auto controller = Utilities::CreateDispatcherQueueControllerForCurrentThread();
auto compositor = winrt::Compositor();
// Create your window...
...
}
void MicaWindow::RegisterWindowClass()
{
auto instance = winrt::check_pointer(GetModuleHandleW(nullptr));
WNDCLASSEX wcex = { sizeof(wcex) };
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = instance;
wcex.hIcon = LoadIconW(instance, IDI_APPLICATION);
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszClassName = ClassName.c_str();
wcex.hIconSm = LoadIconW(wcex.hInstance, IDI_APPLICATION);
winrt::check_bool(RegisterClassExW(&wcex)); // check if the window class was registered successfully
}
Метод winrt::init_apartment
по умолчанию используется с несколькими потоками. Если приложению требуется один поток, например, пример WebView2, можно легко задать тип.
winrt::init_apartment(winrt::apartment_type::single_threaded);
Теперь можно использовать функцию CreateWindowEx()
для создания окна. Затем необходимо создать целевой объект окна и задать его в качестве корневого элемента, чтобы указать, к какому слою следует применить Mica. Наконец, убедитесь, что Mica поддерживается окном и целевым объектом.
В примере Win32 Mica создаются классы DesktopWindow и MicaWindow для выполнения этой задачи. Эти классы определяют следующее: ClassName
, windowTitle
, m_target
, m_micaController
, и m_isMicaSupported
.
Из WinMain.cpp
// Mica window is inherited from the MicaWindow class, which is an extension of the DesktopWindow Class.
// Here, we initialize the main window and set the title.
auto window = MicaWindow(compositor, L"Hello, Mica!");
// Create the main window and enable Mica.
MicaWindow::MicaWindow(const winrt::Compositor& compositor, const std::wstring& windowTitle)
{
auto instance = winrt::check_pointer(GetModuleHandleW(nullptr));
WINRT_ASSERT(!m_window); // check that window is not initialized
WINRT_VERIFY(
// Window Properties
CreateWindowExW(
WS_EX_COMPOSITED,
ClassName.c_str(), // declared in MicaWindow.h and defined above
windowTitle.c_str(),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
800, 600,
nullptr,
nullptr,
instance,
this
));
// Check that the window was created successfully.
WINRT_ASSERT(m_window);
ShowWindow(m_window, SW_SHOWDEFAULT);
UpdateWindow(m_window);
// The Mica controller needs to set a target with a root to recognize the visual base layer.
m_target = CreateWindowTarget(compositor);
// Need to set a root before we can enable Mica.
m_target.Root(compositor.CreateContainerVisual());
m_micaController = winrt::MicaController();
m_isMicaSupported = m_micaController.SetTarget(winrt::Microsoft::UI::WindowId{ reinterpret_cast<uint64_t>(m_window) }, m_target);
}
Использование Mica в приложениях Win32 WebView2
В большинстве приложений Win32 используются согласованные принципы применения Mica. В процессе webView2 выполняются основные шаги из приведенных выше инструкций Win32. Однако в этом случае необходимо указать однопоточный процесс из функции WinRT init_apartment
.
Совет
Код в этом разделе взят из примера Windows App SDK WebView2 Mica в GitHub. См. полный код в репозитории GitHub.
Чтобы приступить к работе, настройте необходимое подразделение, контроллер, компоновщик, целевой объект и корневой каталог. По умолчанию функция WinRT init_apartment
является многопоточной, однако функция WebView2 изначально является однопоточной. Чтобы задать init_apartment
как однопоточную функцию, передайте параметр winrt::apartment_type::single_threaded
. В примере Mica WebView2 мы упростим синтаксис, создав отдельный класс для функций веб-представления, на который ссылается следующий код.
Из Main.cpp
int __stdcall WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PSTR, _In_ int)
{
winrt::init_apartment(winrt::apartment_type::single_threaded);
// Enable referencing the WindowsAppSDK from an unpackaged app.
// Remember to have a matching Microsoft.WindowsAppRuntime.Redist installed.
// https://learn.microsoft.com/windows/apps/windows-app-sdk/deploy-unpackaged-apps
Utilities::WindowsAppSDKBootstrapperContext sdkContext;
CompositionWindow::RegisterWindowClass();
// A dispatcher queue is required to be able to create a compositor.
auto controller = Utilities::CreateDispatcherQueueControllerForCurrentThread();
auto compositor = winrt::Compositor();
auto window = WebView2Window(compositor, L"Hello, WebView2!");
...
}
Полную демонстрацию класса WebView2Window и его интеграцию с Mica см. в примере Windows App SDK WebView2 Mica на GitHub. Обратите внимание, как классы CompositionWindow и WebView2Window обрабатывают сообщения, инициализируют среду веб-представления и удаляют контроллер окна после закрытия окна.
Связанные статьи
Материалы, уровень и повышение прав, примеры Mica пакета SDK для приложений Windows
Windows developer