Windows 11 向け Win32 デスクトップ アプリでマイカを適用する
マイカは、ユーザーのテーマとデスクトップの壁紙を組み込み、高度にカスタマイズされた外観を作成する不透明な素材です。 ユーザーが画面上でウィンドウを動かすと、マイカ素材が動的に適応し、アプリケーションの下にある壁紙を使用して豊富な視覚エフェクトを作成します。 さらに、この素材は、アプリが非アクティブな場合に中間色に戻ることで、ユーザーが現在のタスクに集中するのに役立ちます。
この記事では、マイカを Win32 アプリの基本レイヤーとして適用し、タイトル バー領域でのアプリケーションと可視性を優先する方法を説明します。 マイカを使用したアプリのレイヤー化について詳しくは、「マイカ素材」をご覧ください。
前提条件
Windows 11 向け Win32 アプリにマイカを適用するには、Windows App SDK を使う必要があります。 次が必要です。
- 最新の Windows App SDK Visual Studio 拡張機能または Microsoft.WindowsAppSDK NuGet パッケージをインストールします。 「Windows App SDK 用のダウンロード」をご覧ください。
- パッケージ化されていないアプリの場合は、Windows App SDK を参照し、WinRT をインストールして、一致する Windowsアプリ ランタイム再頒布可能ファイル (Microsoft.WindowsAppRuntime.Redist) をインストールします。 「外部の場所でパッケージ化されたまたはパッケージ化されていないフレームワーク依存のアプリ向け Windows App SDK 展開ガイド」を参照してください。
Win32 アプリでマイカを使用する方法
アプリでマイカを使うには、MicaController クラスを使います。 このクラスは、システム背景素材のレンダリングと、マイカ素材に関するシステム ポリシーの処理の両方を管理します。
MicaController は、既定でシステムのライト テーマとダーク テーマに反応します。 この動作をオーバーライドするには、MicaController に次のプロパティを渡します。
ヒント
このセクションのコードは、GitHub の Windows App SDK Win32 マイカ サンプルのものです。 完全なコードについては、GitHub リポジトリをご覧ください。 これらの例では、C++/WinRT を使います。
マイカを有効にするには、Windows App SDK、コンポジター、DispatcherQueue への参照が必要です。
この例では、パッケージ化されていないアプリを設定するために以下のことを行う方法を示します。
- WinRT を初期化します。
- パッケージ化されていないアプリから WindowsAppSDK を参照します。
- 詳細については、「外部の場所でパッケージ化されているか、パッケージ化されていないアプリの Windows App SDK ランタイムを使用する」を参照してください。
- コード例については、Utilities.h の
WindowsAppSDKBootstrapperContext
を参照してください。
- ウィンドウ クラスを登録します。
- マイカ ディスパッチャー キュー コントローラーを作成します
- WinRT コンポジターを初期化します。
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...
...
}
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 マイカ サンプルでは、この処理を行うために DesktopWindow と MicaWindow クラスを作成します。 これらのクラスでは、ClassName
、windowTitle
、m_target
、m_micaController
、m_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!");
// 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 App 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 App SDK WebView2 マイカ サンプルを参照してください。 CompositionWindow と WebView2Window クラスがメッセージを処理し、Web ビュー環境を初期化し、ウィンドウが閉じられたらウィンドウ コントローラーを削除する方法に注意してください。
関連記事
Windows developer