Share via


Aplicar o Mica em aplicativos de desktop do Win32 para Windows 11

O Mica é um material opaco que incorpora o tema do usuário e o papel de parede do desktop para criar uma aparência altamente personalizada. À medida que o usuário move a janela pela tela, o material de Mica se adapta dinamicamente para criar uma visualização avançada usando o papel de parede sob o aplicativo. Além disso, o material ajuda os usuários a se concentrarem na tarefa atual, recuando para uma cor neutra quando o aplicativo está inativo.

Este artigo descreve como aplicar o Mica como a camada base do aplicativo do Win32, priorizando o aplicativo e a visibilidade na área da barra de título. Para obter mais informações sobre a colocação em camadas de aplicativo com o Mica, consulte o Material do Mica.

Pré-requisitos

Para aplicar o Mica a um aplicativo do Win32 para Windows 11, você precisa usar o SDK do Aplicativo Windows. Você precisará do seguinte:

Como usar o Mica em aplicativos do Win32

Para usar o Mica em seu aplicativo, use a classe MicaController. Essa classe gerencia tanto a renderização do material de pano de fundo do sistema quanto a manipulação da política do sistema para o material de Mica.

O MicaController reage aos temas Claro e Escuro do sistema por padrão. Para substituir esse comportamento, você pode passar as seguintes propriedades para o MicaController:

Dica

O código nesta seção é obtido do exemplo de Mica do SDK do Aplicativo Windows Win32 no GitHub. Consulte o repositório do GitHub para obter o código completo. Esses exemplos usam C++/WinRT.

Para habilitar o Mica, você precisa de uma referência ao SDK do Aplicativo Windows, um Compositor e um DispatcherQueue.

Este exemplo mostra como fazer o seguinte para configurar um aplicativo não empacotado:

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

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

O método winrt::init_apartment é de vários thread por padrão. Se o aplicativo exigir um único thread, como o Exemplo de WebView2, você poderá definir facilmente o tipo.

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

Agora você pode usar a função CreateWindowEx() para criar uma janela. Em seguida, você precisa criar um destino de janela e defini-lo como a raiz para especificar a camada à qual aplicar o Mica. Por fim, afirme que o Mica tem suporte pela janela e pelo destino.

O exemplo do Mica do Win32 cria as classes DesktopWindow e MicaWindow para fazer esse trabalho. Essas classes definem: ClassName, windowTitle, m_target, m_micaController e m_isMicaSupported.

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

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

Como usar o Mica em aplicativos do Win32 para WebView2

Os princípios fundamentais da aplicação do Mica são consistentes na maioria dos aplicativos do Win32. O processo para WebView2 segue as etapas básicas das instruções do Win32 mostradas anteriormente. No entanto, nesse caso, você precisará especificar um único processo encadeado do recurso do WinRT init_apartment.

Dica

O código nesta seção é obtido do Exemplo de Mica do SDK do Aplicativo Windows para WebView2 no GitHub. Consulte o repositório do GitHub para obter o código completo.

Para começar, configure o apartamento, o controlador, o compositor, o destino e a raiz necessários. Por padrão, a função WinRT init_apartment é de vários thread, mas o WebView2 é inerentemente de thread único. Para definir init_apartment como um thread único, passe o parâmetro winrt::apartment_type::single_threaded. No exemplo do Mica para WebView2, simplificamos a sintaxe criando uma classe separada para funções de exibição da Web, referenciadas no código a seguir.

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

    ...
}

Para obter uma demonstração completa da classe WebView2Window e sua integração com o Mica, consulte o Exemplo de Mica do SDK do Aplicativo Windows para WebView2 em GitHub. Observe como as classes CompositionWindow e WebView2Window lidam com mensagens, inicializam o ambiente de exibição da Web e excluem o controlador de janela depois que a janela é fechada.

Materiais, Camadas e Elevação, Exemplos de Mica do SDK do Aplicativo Windows