在適用於 Windows 11 的 Win32 傳統型應用程式中套用 Mica
Mica 是一種不透明的材質,其中包含使用者的主題和桌面桌布,以建立高度個人化的外觀。 當使用者在畫面上移動視窗時,Mica 材質會動態調整,以使用應用程式下方的桌布來建立豐富的視覺效果。 此外,當應用程式處於非使用中狀態時,材質可協助使用者專注於目前的工作。
本文說明如何套用 Mica 做為 Win32 應用程式的基底層,並在標題列區域中將應用程式和可見度設為優先順序。 如需使用 Mica 進行應用程式分層的詳細資訊,請參閱 Mica 材質。
必要條件
若要將 Mica 套用至適用於 Windows 11 的 Win32 應用程式,您必須使用 Windows 應用程式 SDK。 您將需要下列項目:
- 安裝最新的 Windows 應用程式 ADK Visual Studio 擴充功能或 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 compositor。
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 存放庫。
若要開始使用,請設定必要的 apartment、controller、compositor、target 和 root。 根據預設,WinRT init_apartment
函式為多重執行緒,但 WebView2 原本就是單一執行緒。 若要將 init_apartment
設定為單一執行緒,請傳遞 winrt::apartment_type::single_threaded
參數。 在 Mica WebView2 範例中,我們會為下列程式碼中參考的 Web 檢視函式建立個別類別來簡化語法。
從 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 類別如何處理訊息、初始化 Web 檢視環境,以及在關閉視窗後隨即刪除視窗控制器。