Windows 11용 데스크톱 앱에서 Mica 또는 Acrylic 자료 적용
Windows 11의 자료는 실제 인공물을 닮은 UX 표면에 적용된 시각 효과입니다. 마이카 및 아크릴과 같은 폐색 재료는 대화형 UI 컨트롤 아래에서 기본 레이어로 사용됩니다.
Mica는 사용자의 테마와 데스크톱 배경 화면을 통합하여 고도로 개인 설정된 모양을 만드는 불투명 재질입니다. Mica는 배경 배경 화면을 한 번만 캡처하여 시각화를 만들 수 있으므로 특히 제목 표시줄 영역에서 앱의 기본 계층에 사용하는 것이 좋습니다.
아크릴은 반투명 유리의 효과를 복제하는 반투명 재질입니다. 이건 플라이아웃 및 상황에 맞는 메뉴와 같은 일시적으로 조명이 없는 화면에서만 사용됩니다.
이 문서에서는 Mica 또는 Acrylic을 Windows 앱 SDK/WinUI 3 XAML 앱의 기본 계층으로 적용하는 방법을 설명합니다.
참고 항목
- 앱 내 AcrylicBrush를 사용하려면 아크릴 재질을 참조하세요.
- Win32 앱에서 배경 자료를 사용하려면 Windows 11용 Win32 데스크톱 앱에서 Mica 적용을 참조하세요.
- UWP/WinUI 2 앱에서 배경 자료를 사용하려면 UWP 또는 아크릴 재질용 WinUI 2로 Mica 적용을 참조하세요.
배경 자료를 사용하는 방법
WinUI 3 갤러리 앱에는 대부분의 WinUI 3 컨트롤, 특징, 기능의 대화형 예제가 포함되어 있습니다. 해당 Microsoft Store에서 앱을 다운로드하거나 GitHub에서 소스 코드를 가져오세요.
앱에 Mica 또는 Acrylic 재질을 적용하려면 속성을 XAML SystemBackdrop(일반적으로 기본 제공 배경 중 하나인 MicaBackdrop 또는 DesktopAcrylicBackdrop) 로 설정합니다SystemBackdrop
.
이러한 요소에는 다음과 같은 속성이 있습니다.SystemBackdrop
- CommandBarFlyoutCommandBar.SystemBackdrop
- ContentIsland.SystemBackdrop
- DesktopWindowXamlSource.SystemBackdrop
- FlyoutBase.SystemBackdrop
- MenuFlyoutPresenter.SystemBackdrop
- Popup.SystemBackdrop
- Window.SystemBackdrop
다음 예제에서는 XAML 및 코드에서 시스템 배경을 설정하는 방법을 보여 줍니다.
Mica
Mica는 일반적으로 앱 창의 배경으로 사용됩니다.
<Window
... >
<Window.SystemBackdrop>
<MicaBackdrop Kind="BaseAlt"/>
</Window.SystemBackdrop>
</Window>
public MainWindow()
{
this.InitializeComponent();
SystemBackdrop = new MicaBackdrop()
{ Kind = MicaKind.BaseAlt };
}
아크릴
아크릴은 일반적으로 플라이아웃과 같은 일시적인 UI의 배경으로 사용됩니다.
<Flyout
... >
<Flyout.SystemBackdrop>
<DesktopAcrylicBackdrop/>
</Flyout.SystemBackdrop>
</Flyout>
Flyout flyout = new Flyout()
{
SystemBackdrop = new DesktopAcrylicBackdrop()
};
시스템 배경 컨트롤러를 사용하는 방법
참고 항목
Windows 앱 SDK 1.3부터 이전 섹션에서 설명한 대로 속성을 XAML Window.SystemBackdrop
로 설정 SystemBackdrop
하여 자료를 적용할 수 있습니다. 이는 재질을 적용하는 데 권장되는 방법입니다.
이 글의 나머지 부분은 Composition MicaController 및 DesktopAcrylicController API의 사용 방법을 보여줍니다.
앱에서 배경 자료를 사용하려면 ISystemBackdropController 인터페이스(MicaController 또는 DesktopAcrylicController)를 구현하는 컨트롤러 중 하나를 사용할 수 있습니다. 이러한 클래스는 시스템 배경 자료의 렌더링과 자료에 대한 시스템 정책 처리를 모두 관리합니다.
Mica를 배경 자료로 사용하려면 MicaController 개체를 만듭니다. Acrylic을 사용하려면 DesktopAcrylicController 개체를 만듭니다. 설정 및 지원 코드는 시스템 배경 자료의 각 유형에 대해 동일합니다.
이 코드는 MicaController
을 만드는 방법을 보여줍니다.
MicaController m_backdropController;
bool TrySetSystemBackdrop()
{
if (MicaController.IsSupported())
{
...
m_backdropController = new MicaController();
...
}
}
// namespace MUCSB = Microsoft::UI::Composition::SystemBackdrops;
winrt::MUCSB::MicaController m_backdropController{ nullptr };
void SetBackground()
{
if (winrt::MUCSB::MicaController::IsSupported())
{
...
m_backdropController = winrt::MUCSB::MicaController();
...
}
}
Mica의 Mica Alt 변형을 사용하려면 개체를 MicaController
만들고 Kind 속성을 MicaKind.BaseAlt로 설정합니다.
MicaController m_backdropController;
bool TrySetSystemBackdrop()
{
if (MicaController.IsSupported())
{
...
m_backdropController = new MicaController()
{
Kind = MicaKind.BaseAlt
};
...
}
}
// namespace MUCSB = Microsoft::UI::Composition::SystemBackdrops;
winrt::MUCSB::MicaController m_backdropController{ nullptr };
void SetBackground()
{
if (winrt::MUCSB::MicaController::IsSupported())
{
...
m_backdropController = winrt::MUCSB::MicaController();
m_backdropController.Kind(winrt::MUCSB::MicaKind::BaseAlt);
...
}
}
이 코드는 DesktopAcrylicController
을 만드는 방법을 보여줍니다.
DesktopAcrylicController m_backdropController;
bool TrySetSystemBackdrop()
{
if (DesktopAcrylicController.IsSupported())
{
...
m_backdropController = new DesktopAcrylicController();
...
}
}
// namespace MUCSB = Microsoft::UI::Composition::SystemBackdrops;
winrt::MUCSB::DesktopAcrylicController m_backdropController{ nullptr };
void SetBackground()
{
if (winrt::MUCSB::DesktopAcrylicController::IsSupported())
{
...
m_backdropController = winrt::MUCSB::DesktopAcrylicController();
...
}
}
controller는 기본적으로 시스템 밝은 테마 및 어두운 테마에 반응합니다. 이 동작을 재정의하려면 컨트롤러에서 다음 속성을 설정할 수 있습니다:
앱에서 배경 자료를 사용하려면 다음 항목이 필요합니다.
시스템 지원
앱이 실행되는 시스템은 배경 자료를 지원해야 합니다. 해당 MicaController.IsSupported 또는 DesktopAcrylicController.IsSupported 메서드를 호출하여 런타임에 배경 자료가 지원되는지 확인합니다.
유효한 대상
해당 ICompositionSupportsSystemBackdrop 인터페이스를 구현하는 대상을 제공해야 합니다. XAML 앱에서 XAML 창 은 이 인터페이스를 구현하고 배경 대상으로 사용됩니다.
SystemBackdropConfiguration 개체
이 SystemBackdropConfiguration은 시스템 배경 컨트롤러에 앱별 정책 정보를 제공하여 시스템 배경 자료를 제대로 구성합니다.
DispatcherQueue 개체입니다.
기본 XAML 스레드에서 사용 가능한 Windows.System.DispatcherQueue가 필요합니다. 이
WindowsSystemDispatcherQueueHelper
예제 코드 또는 WinUI 3 갤러리 샘플에서 클래스를 참조하세요.
예: Windows AppSDK/WinUI 3 앱에서 Mica 사용
이 예제에서는 XAML 앱에서 Mica 배경 자료를 설정하는 방법을 보여줍니다.
팁
또한 GitHub에서 다음 예제 프로젝트를 참조하세요.
C#: WinUI3 갤러리의 SampleSystemBackdropsWindow입니다.
C++/WinRT: Windows 앱 SDK Mica 샘플입니다.
using Microsoft.UI.Composition.SystemBackdrops;
using Microsoft.UI.Xaml;
using System.Runtime.InteropServices; // For DllImport
using WinRT; // required to support Window.As<ICompositionSupportsSystemBackdrop>()
public sealed partial class MainWindow : Window
{
WindowsSystemDispatcherQueueHelper m_wsdqHelper; // See below for implementation.
MicaController m_backdropController;
SystemBackdropConfiguration m_configurationSource;
public MainWindow()
{
this.InitializeComponent();
TrySetSystemBackdrop();
}
bool TrySetSystemBackdrop()
{
if (Microsoft.UI.Composition.SystemBackdrops.MicaController.IsSupported())
{
m_wsdqHelper = new WindowsSystemDispatcherQueueHelper();
m_wsdqHelper.EnsureWindowsSystemDispatcherQueueController();
// Create the policy object.
m_configurationSource = new SystemBackdropConfiguration();
this.Activated += Window_Activated;
this.Closed += Window_Closed;
((FrameworkElement)this.Content).ActualThemeChanged += Window_ThemeChanged;
// Initial configuration state.
m_configurationSource.IsInputActive = true;
SetConfigurationSourceTheme();
m_backdropController = new Microsoft.UI.Composition.SystemBackdrops.MicaController();
// Enable the system backdrop.
// Note: Be sure to have "using WinRT;" to support the Window.As<...>() call.
m_backdropController.AddSystemBackdropTarget(this.As<Microsoft.UI.Composition.ICompositionSupportsSystemBackdrop>());
m_backdropController.SetSystemBackdropConfiguration(m_configurationSource);
return true; // succeeded
}
return false; // Mica is not supported on this system
}
private void Window_Activated(object sender, WindowActivatedEventArgs args)
{
m_configurationSource.IsInputActive = args.WindowActivationState != WindowActivationState.Deactivated;
}
private void Window_Closed(object sender, WindowEventArgs args)
{
// Make sure any Mica/Acrylic controller is disposed
// so it doesn't try to use this closed window.
if (m_backdropController != null)
{
m_backdropController.Dispose();
m_backdropController = null;
}
this.Activated -= Window_Activated;
m_configurationSource = null;
}
private void Window_ThemeChanged(FrameworkElement sender, object args)
{
if (m_configurationSource != null)
{
SetConfigurationSourceTheme();
}
}
private void SetConfigurationSourceTheme()
{
switch (((FrameworkElement)this.Content).ActualTheme)
{
case ElementTheme.Dark: m_configurationSource.Theme = Microsoft.UI.Composition.SystemBackdrops.SystemBackdropTheme.Dark; break;
case ElementTheme.Light: m_configurationSource.Theme = Microsoft.UI.Composition.SystemBackdrops.SystemBackdropTheme.Light; break;
case ElementTheme.Default: m_configurationSource.Theme = Microsoft.UI.Composition.SystemBackdrops.SystemBackdropTheme.Default; break;
}
}
}
class WindowsSystemDispatcherQueueHelper
{
[StructLayout(LayoutKind.Sequential)]
struct DispatcherQueueOptions
{
internal int dwSize;
internal int threadType;
internal int apartmentType;
}
[DllImport("CoreMessaging.dll")]
private static extern int CreateDispatcherQueueController([In] DispatcherQueueOptions options, [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object dispatcherQueueController);
object m_dispatcherQueueController = null;
public void EnsureWindowsSystemDispatcherQueueController()
{
if (Windows.System.DispatcherQueue.GetForCurrentThread() != null)
{
// one already exists, so we'll just use it.
return;
}
if (m_dispatcherQueueController == null)
{
DispatcherQueueOptions options;
options.dwSize = Marshal.SizeOf(typeof(DispatcherQueueOptions));
options.threadType = 2; // DQTYPE_THREAD_CURRENT
options.apartmentType = 2; // DQTAT_COM_STA
CreateDispatcherQueueController(options, ref m_dispatcherQueueController);
}
}
}
// pch.h
...
#include <winrt/Microsoft.UI.Composition.SystemBackdrops.h>
#include <winrt/Windows.System.h>
#include <dispatcherqueue.h>
// MainWindow.xaml.h
...
namespace winrt
{
namespace MUC = Microsoft::UI::Composition;
namespace MUCSB = Microsoft::UI::Composition::SystemBackdrops;
namespace MUX = Microsoft::UI::Xaml;
namespace WS = Windows::System;
}
...
struct MainWindow : MainWindowT<MainWindow>
{
winrt::MUCSB::SystemBackdropConfiguration m_configuration{ nullptr };
winrt::MUCSB::MicaController m_backdropController{ nullptr };
winrt::MUX::Window::Activated_revoker m_activatedRevoker;
winrt::MUX::Window::Closed_revoker m_closedRevoker;
winrt::MUX::FrameworkElement::ActualThemeChanged_revoker m_themeChangedRevoker;
winrt::MUX::FrameworkElement m_rootElement{ nullptr };
winrt::WS::DispatcherQueueController m_dispatcherQueueController{ nullptr };
MainWindow::MainWindow()
{
InitializeComponent();
SetBackground();
m_closedRevoker = this->Closed(winrt::auto_revoke, [&](auto&&, auto&&)
{
if (nullptr != m_backdropController)
{
m_backdropController.Close();
m_backdropController = nullptr;
}
if (nullptr != m_dispatcherQueueController)
{
m_dispatcherQueueController.ShutdownQueueAsync();
m_dispatcherQueueController = nullptr;
}
});
}
void SetBackground()
{
if (winrt::MUCSB::MicaController::IsSupported())
{
// We ensure that there is a Windows.System.DispatcherQueue on the current thread.
// Always check if one already exists before attempting to create a new one.
if (nullptr == winrt::WS::DispatcherQueue::GetForCurrentThread() &&
nullptr == m_dispatcherQueueController)
{
m_dispatcherQueueController = CreateSystemDispatcherQueueController();
}
// Setup the SystemBackdropConfiguration object.
SetupSystemBackdropConfiguration();
// Setup Mica on the current Window.
m_backdropController = winrt::MUCSB::MicaController();
m_backdropController.SetSystemBackdropConfiguration(m_configuration);
m_backdropController.AddSystemBackdropTarget(
this->m_inner.as<winrt::MUC::ICompositionSupportsSystemBackdrop>());
}
else
{
// The backdrop material is not supported.
}
}
winrt::WS::DispatcherQueueController CreateSystemDispatcherQueueController()
{
DispatcherQueueOptions options
{
sizeof(DispatcherQueueOptions),
DQTYPE_THREAD_CURRENT,
DQTAT_COM_NONE
};
::ABI::Windows::System::IDispatcherQueueController* ptr{ nullptr };
winrt::check_hresult(CreateDispatcherQueueController(options, &ptr));
return { ptr, take_ownership_from_abi };
}
void SetupSystemBackdropConfiguration()
{
m_configuration = winrt::MUCSB::SystemBackdropConfiguration();
// Activation state.
m_activatedRevoker = this->Activated(winrt::auto_revoke,
[&](auto&&, MUX::WindowActivatedEventArgs const& args)
{
m_configuration.IsInputActive(
winrt::MUX::WindowActivationState::Deactivated != args.WindowActivationState());
});
// Initial state.
m_configuration.IsInputActive(true);
// Application theme.
m_rootElement = this->Content().try_as<winrt::MUX::FrameworkElement>();
if (nullptr != m_rootElement)
{
m_themeChangedRevoker = m_rootElement.ActualThemeChanged(winrt::auto_revoke,
[&](auto&&, auto&&)
{
m_configuration.Theme(
ConvertToSystemBackdropTheme(m_rootElement.ActualTheme()));
});
// Initial state.
m_configuration.Theme(
ConvertToSystemBackdropTheme(m_rootElement.ActualTheme()));
}
}
winrt::MUCSB::SystemBackdropTheme ConvertToSystemBackdropTheme(
winrt::MUX::ElementTheme const& theme)
{
switch (theme)
{
case winrt::MUX::ElementTheme::Dark:
return winrt::MUCSB::SystemBackdropTheme::Dark;
case winrt::MUX::ElementTheme::Light:
return winrt::MUCSB::SystemBackdropTheme::Light;
default:
return winrt::MUCSB::SystemBackdropTheme::Default;
}
}
...
};
...
관련된 문서
Windows developer