Condividi tramite


Applica Mica alle app desktop Win32 per Windows 11

Mica è un materiale opaco che incorpora il tema e lo sfondo del desktop dell'utente per creare un aspetto altamente personalizzato. Quando l'utente sposta la finestra sullo schermo, il materiale Mica si adatta dinamicamente per creare una visualizzazione avanzata usando lo sfondo sotto l'applicazione. Inoltre, il materiale aiuta gli utenti a concentrarsi sull'attività corrente eseguendo il fallback a un colore neutro quando l'app è inattiva.

Questo articolo descrive come applicare Mica come livello di base dell'app Win32, assegnando priorità all'applicazione e alla visibilità nell'area della barra del titolo. Per altre informazioni sulla sovrapposizione delle app con Mica, vedi materiale Mica.

Prerequisiti

Per applicare Mica a un'app Win32 per Windows 11, è necessario usare l'SDK per app di Windows. È necessario disporre di quanto segue:

Come usare Mica nelle app Win32

Per usare mica nell'app, usa la classe MicaController. Questa classe gestisce sia il rendering del materiale di sfondo del sistema che la gestione dei criteri di sistema per il materiale mica.

Per impostazione predefinita, MicaController reagisce ai temi chiaro e scuro del sistema. Per eseguire l'override di questo comportamento, è possibile passare le proprietà seguenti a MicaController:

Suggerimento

Il codice in questa sezione è tratto dall'esempio Win32 Mica dell'SDK per app di Windows su GitHub. Vedi il repository GitHub per il codice completo. Questi esempi usano C++/WinRT.

Per abilitare Mica, è necessario un riferimento all'SDK per app di Windows, a Compositor e a DispatcherQueue.

Questo esempio illustra come eseguire le operazioni seguenti per configurare un'app non in pacchetto:

Da 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...
    ...
}

Da 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
}

Il metodo winrt::init_apartment è multithread per impostazione predefinita. Se l'app richiede un singolo thread, come l'esempio WebView2, è possibile impostare facilmente il tipo.

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

Ora puoi usare la funzione CreateWindowEx() per creare una finestra. Devi quindi creare una destinazione della finestra e impostarla come radice per specificare il livello a cui applicare Mica. Infine, assicurati che Mica sia supportata dalla finestra e dalla destinazione.

L'esempio Win32 Mica crea le classi DesktopWindow e MicaWindow per eseguire questa operazione. Queste classi definiscono: ClassName, windowTitle, m_target, m_micaController e m_isMicaSupported.

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

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

Come usare Mica nelle app Win32 WebView2

I principi fondamentali dell'applicazione di Mica sono coerenti nella maggior parte delle applicazioni Win32. Il processo per WebView2 segue i passaggi di base delle istruzioni Win32 illustrate in precedenza. Tuttavia, in questo caso è necessario specificare un processo a thread singolo dalla funzionalità init_apartment di WinRT.

Suggerimento

Il codice in questa sezione è tratto dall'esempio WebView2 Mica dell'SDK per app di Windows su GitHub. Vedi il repository GitHub per il codice completo.

Per iniziare, configura l'apartment, il controller, il compositor, la destinazione e la radice necessari. Per impostazione predefinita, la funzione WinRT init_apartment è a thread multiplo, ma WebView2 è intrinsecamente a thread singolo. Per impostare init_apartment come singolo thread, passa il parametro winrt::apartment_type::single_threaded. Nell'esempio Mica WebView2 semplifichiamo la sintassi creando una classe separata per le funzioni di visualizzazione Web a cui si fa riferimento nel codice seguente.

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

    ...
}

Per una dimostrazione completa della classe WebView2Window e della relativa integrazione con Mica, vedi l'esempio WebView2 Mica dell'SDK per app di Windows su GitHub. Nota come le classi CompositionWindow e WebView2Window gestiscono i messaggi, inizializzano l'ambiente di visualizzazione Web ed eliminano il controller finestra dopo la chiusura della stessa.

Materiali, Livelli ed elevazionedei livelli, esempi di Mica dell'SDK per app di Windows