Windows 11용 Win32 데스크톱 앱에 Mica 적용
Mica는 사용자의 테마와 데스크톱 배경 화면을 통합하여 고도로 개인 설정된 모양을 만드는 불투명 재질입니다. Mica 재질은 사용자가 화면에서 창을 이동할 때 애플리케이션 아래의 배경 화면을 사용하여 풍부한 시각화를 만들도록 동적 조정됩니다. 또한 Mica는 앱이 비활성 상태일 때 중간색으로 대체하여 사용자가 현재 작업에 집중하도록 도와줍니다.
이 문서는 제목 표시줄 영역에서 애플리케이션과 표시 유형을 우선시하여 Win32 앱의 기본 계층으로 Mica를 적용하는 방법을 설명합니다. Mica를 사용한 앱 계층화에 대한 자세한 내용은 Mica 재료를 참조하세요.
전제 조건
Windows 11용 Win32 앱에 Mica를 적용하려면 Windows 앱 SDK를 사용해야 합니다. 다음 항목이 필요합니다.
- 최신 Windows App SDK Visual Studio Extension 또는 Microsoft.WindowsAppSDK NuGet 패키지를 설치합니다. Windows 앱 SDK 다운로드를 참조하세요.
- 패키징되지 않은 앱의 경우, Windows 앱 SDK를 참조하고 WinRT를 설치하며, 일치하는 Windows 앱 런타임 재배포 가능 패키지(Microsoft.WindowsAppRuntime.Redist)를 설치합니다. 외부 위치로 패키지되거나 패키지되지 않은 프레임워크 종속 앱을 위한 Windows 앱 SDK 배포 가이드를 참조하세요.
Win32 앱에서 Mica를 사용하는 방법
앱에서 Mica를 사용하려면 MicaController 클래스를 사용합니다. 이 클래스는 시스템 배경 재료의 렌더링과 Mica 재료에 대한 전체 시스템 정책 처리를 관리합니다.
MicaController는 기본적으로 시스템 밝은 테마 및 어두운 테마에 반응합니다. 이 동작을 재정의하려면 다음 속성을 MicaController에 전달할 수 있습니다.
팁
이 섹션의 코드는 GitHub의 Windows 앱 SDK Win32 Mica 샘플에서 가져왔습니다. 전체 코드는 GitHub 리포지토리를 참조하세요. 다음 예제에서는 C++/WinRT를 사용합니다.
Mica를 활성하려면 Windows 앱 SDK, Compositor 및 DispatcherQueue에 대한 참조가 필요합니다.
이 예에서는 다음을 수행하여 패키지되지 않은 앱을 설정하는 방법을 보여줍니다.
- WinRT를 초기화합니다.
- 패키징되지 않은 앱에서 WindowsAppSDK를 참조하세요.
- 자세한 내용은 외부 위치로 패키징되는 앱 또는 패키징되지 않은 앱에 Windows App SDK 런타임 사용을 참조하세요.
- Utilities.h의
WindowsAppSDKBootstrapperContext
에서 코드 예를 참조하세요.
- 창 클래스를 등록합니다.
- Mica 디스패처 큐 컨트롤러 만들기
- WinRT 작성기를 초기화합니다.
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
를 정의합니다.
// 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);
}
Win32 WebView2 앱에서 Mica를 사용하는 방법
Mica를 적용하는 기본 원칙은 대부분의 Win32 애플리케이션에서 일관됩니다. WebView2 프로세스는 이전에 표시된 Win32 지침의 기본 단계를 따릅니다. 그러나 이 경우에서는 WinRT의 init_apartment
기능에서 단일 스레드 프로세스를 지정해야 합니다.
팁
이 섹션의 코드는 GitHub의 Windows 앱 SDK WebView2 Mica 샘플에서 가져왔습니다. 전체 코드는 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와의 통합에 대한 전체 데모를 확인하려면 GitHub의 Windows 앱 SDK WebView2 Mica 샘플을 참조하세요. CompositionWindow 및 WebView2Window 클래스가 메시지를 처리하고, 웹 보기 환경을 초기화하고, 창이 닫히면 창 컨트롤러를 삭제하는 방법에 유의합니다.
관련 문서
Windows developer