Windows 11 向け Win32 デスクトップ アプリでマイカを適用する

マイカは、ユーザーのテーマとデスクトップの壁紙を組み込み、高度にカスタマイズされた外観を作成する不透明な素材です。 Micaは、その視覚化を作成するために背景の壁紙を一度だけキャプチャするため、パフォーマンスのために設計されています。 ユーザーがウィンドウの位置を変更すると、マイカ素材はアプリケーションの下の壁紙に基づいて動的に適応します。 さらに、この素材は、アプリが非アクティブな場合に中間色に戻ることで、ユーザーが現在のタスクに集中するのに役立ちます。

ヒント

Mica Alt は、デスクトップの背景色の濃淡が強いマイカのバリエーションで、タブ付きのタイトル バーがあるアプリに便利です。 Mica Alt を使用するには、 MicaController.KindMicaKind.BaseAlt (この記事全体で使用されているのと同じコントローラー) に設定します。 詳細については、「 デスクトップ アプリでマイカまたはアクリル素材を適用する」を参照してください。 設計ガイダンスについては、 マイカの資料を参照してください。

この記事では、マイカを Win32 アプリの基本レイヤーとして適用し、タイトル バー領域でのアプリケーションと可視性を優先する方法を説明します。 マイカを使用したアプリのレイヤー化について詳しくは、「マイカ素材」をご覧ください。

前提条件

Windows 11 向け Win32 アプリにマイカを適用するには、Windows アプリ SDK を使う必要があります。 以下が必要です:

Win32 アプリでマイカを使用する方法

アプリでマイカを使うには、MicaController クラスを使います。 このクラスは、システム背景素材のレンダリングと、マイカ素材に関するシステム ポリシーの処理の両方を管理します。

MicaController は、既定でシステムのライト テーマとダーク テーマに反応します。 この動作をオーバーライドするには、MicaController に次のプロパティを渡します。

ヒント

このセクションのコードは、GitHub の Windows アプリ SDK Win32 マイカ サンプルのものです。 完全なコードについては、GitHub リポジトリをご覧ください。 これらの例では、C++/WinRT を使います。

マイカを有効にするには、Windows アプリ SDK、コンポジターDispatcherQueue への参照が必要です。

この例では、パッケージ化されていないアプリを設定するために以下のことを行う方法を示します。

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

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
}

winrt::init_apartment メソッドは既定ではマルチスレッドです。 WebView2 サンプルのように、シングルスレッドが必要なアプリの場合は、種類を簡単に設定できます。

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

これで、CreateWindowEx() 関数を使ってウィンドウを作成できます。 次に、ウィンドウ ターゲットを作成し、それをルートとして設定して、マイカを適用するレイヤーを指定する必要があります。 最後に、ウィンドウとターゲットによってマイカがサポートされていることをアサートします。

Win32 マイカ サンプルでは、この処理を行うために DesktopWindowMicaWindow クラスを作成します。 これらのクラスでは、ClassNamewindowTitlem_targetm_micaControllerm_isMicaSupported が定義されています。

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

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

Win32 WebView2 アプリでマイカを使用する方法

マイカを適用する基本的な原則は、ほとんどの Win32 アプリケーションで同じです。 WebView2 でのプロセスは、前に示した Win32 の説明の基本的な手順に従います。 ただし、この場合は、WinRT の init_apartment 機能からシングルスレッド プロセスを指定する必要があります。

ヒント

このセクションのコードは、GitHub の Windows アプリ SDK WebView2 マイカ サンプルのものです。 完全なコードについては、GitHub リポジトリをご覧ください。

作業を始めるには、必要なアパートメント、コントローラー、コンポジター、ターゲット、ルートを設定します。 WinRT の init_apartment 関数は既定ではマルチスレッドですが、WebView2 は本質的にシングルスレッドです。 init_apartment をシングルスレッドとして設定するには、winrt::apartment_type::single_threaded パラメーターを渡します。 マイカ 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 マイカ サンプルを参照してください。 CompositionWindowWebView2Window クラスがメッセージを処理し、Web ビュー環境を初期化し、ウィンドウが閉じられたらウィンドウ コントローラーを削除する方法に注意してください。

素材レイヤー化と昇格Windows アプリ SDK マイカ サンプル