Anwenden von Mica in Win32-Desktopanwendungen für Windows 11

Mica ist ein undurchsichtiges Material, das das Design und die Desktop-Hintergrundbilder des Benutzers enthält, um ein sehr personalisiertes Aussehen zu schaffen. Wenn der Benutzer das Fenster über den Bildschirm verschiebt, passt sich das Mica-Material dynamisch an, um eine umfassende Visualisierung mithilfe der Hintergrundbilder unterhalb der Anwendung zu erstellen. Darüber hinaus hilft das Material Benutzern, sich auf die aktuelle Aufgabe zu konzentrieren, indem sie zu einer neutralen Farbe zurückkehren, wenn die App inaktiv ist.

In diesem Artikel wird beschrieben, wie Mica als Basisebene Ihrer Win32-App angewendet wird, wobei Anwendung und Sichtbarkeit im Titelleistenbereich priorisiert werden. Weitere Informationen zur App-Layering mit Mica finden Sie unter Mica-Material.

Voraussetzungen

Um Mica auf eine Win32-App für Windows 11 anzuwenden, müssen Sie das Windows App SDK verwenden. Sie benötigen Folgendes:

So verwenden Sie Mica in Win32-Apps

Um Mica in Ihrer App zu verwenden, verwenden Sie die MicaController-Klasse. Diese Klasse verwaltet sowohl das Rendern des Systemhintergrundmaterials als auch die Behandlung von Systemrichtlinien für das Mica-Material.

Der MicaController reagiert standardmäßig auf die System-Designs „Hell“ und „Dunkel“. Um dieses Verhalten außer Kraft zu setzen, können Sie die folgenden Eigenschaften an den MicaController übergeben:

Tipp

Der Code in diesem Abschnitt wird aus dem Windows App SDK Win32 Mica-Beispiel auf GitHub genommen. Weitere Informationen finden Sie im GitHub Repo für den vollständigen Code. Diese Beispiele verwenden C++/WinRT.

Um Mica zu aktivieren, benötigen Sie einen Verweis auf das Windows App SDK, einen Compositor und eine DispatcherQueue.

In diesem Beispiel wird gezeigt, wie Sie folgendes ausführen, um eine nicht gepackte App einzurichten:

Über 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...
    ...
}

Über MicaWindow.cpp

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
}

Die winrt::init_apartment-Methode verfügt standardmäßig über Multi-Threads. Wenn Ihre App einen einzelnen Thread erfordert, z. B. das WebView2-Beispiel, können Sie den Typ einfach festlegen.

winrt::init_apartment(winrt::apartment_type::single_threaded);

Jetzt können Sie die CreateWindowEx()-Funktion verwenden, um ein Fenster zu erstellen. Anschließend müssen Sie ein Fensterziel erstellen und als Stamm festlegen, auf welche Ebene Mica angewendet werden soll. Vergewissern Sie sich schließlich, dass Mica vom Fenster und Ziel unterstützt wird.

Das Win32 Mica-Beispiel erstellt die Klassen DesktopWindow und MicaWindow, um diese Arbeit zu erledigen. Diese Klassen definieren: ClassName, windowTitle, m_target, m_micaController und m_isMicaSupported.

Über 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!");

Über MicaWindow.cpp

// 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);
}

Verwenden von Mica in Win32 WebView2-Apps

Die grundlegenden Prinzipien der Anwendung von Mica sind in den meisten Win32-Anwendungen konsistent. Der Prozess für WebView2 folgt den grundlegenden Schritten aus den zuvor gezeigten Win32-Anweisungen. In diesem Fall müssen Sie jedoch einen einzelnen Threadvorgang aus der init_apartment-Funktion von WinRT angeben.

Tipp

Der Code in diesem Abschnitt wird aus dem Windows App SDK WebView2 Mica-Beispiel auf GitHub genommen. Weitere Informationen finden Sie im GitHub Repo für den vollständigen Code.

Um zu beginnen, richten Sie Apartment, Controller, Compositor, Ziel und Stamm ein, die erforderlich sind. Standardmäßig ist die init_apartment-Funktion von WinRT in Multi-Threads, aber WebView2 ist inhärent in Einzel-Threads. Um init_apartment als Einzel-Thread festzulegen, übergeben Sie den winrt::apartment_type::single_threaded-Parameter. Im Mica WebView2-Beispiel vereinfachen wir die Syntax, indem wir eine separate Klasse für Webansichtsfunktionen erstellen, auf die im folgenden Code verwiesen wird.

Von 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!");

    ...
}

Eine vollständige Demonstration der WebView2Window-Klasse und deren Integration mit Mica finden Sie im Windows App SDK WebView2 Mica-Beispiel für GitHub. Beachten Sie, wie die Klassen CompositionWindow und WebView2Window Nachrichten behandeln, die Webansichtsumgebung initialisieren und den Fenstercontroller löschen, sobald das Fenster geschlossen wurde.

Materialien, Ebenen und Höhe, Windows App SDK-Mica-Beispiele