MFCでタスクバーのようなアプリの作り方

MFC

機械上で動作するアプリケーションなどで、タスクバーのように画面の端に固定してその上には何もかぶらないようにしたい場合があります。

公式ドキュメントによると、アプリケーションデスクトップツールバー(以下AppBar)を使用することでタスクバーのようなウィンドウを作成することができます。

アプリケーション デスクトップ ツール バーの使用 - Win32 apps
アプリケーション デスクトップ ツール バー (アプリ バーとも呼ばれます) は、Windows タスク バーに似たウィンドウです。

この記事では、MFCでタスクバーのようなアプリの作り方について解説します。

ウィンドウをディスプレイ端に配置

始めに、タスクバーのように固定するため対象のウィンドウをディスプレイの端に移動します。

右端や下端に配置する場合にはディスプレイサイズが必要になるため、以下の方法でディスプレイサイズを取得してMoveWindowやSetWindowPosでウィンドウを移動します。

// ディスプレイサイズ(解像度)取得
int sx = ::GetSystemMetrics(SM_CXSCREEN);
int sy = ::GetSystemMetrics(SM_CYSSCREEN);

// ワークエリア(タスクバー以外の領域)取得
RECT rc = { 0 };
::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rc, NULL);
int sx = rc.right - rc.left;
int sy = rc.bottom - rc.top;

ここではタスクバーのようなアプリにするために最前面固定にし、右端に配置します。

int w = 50;
int h = sy;
int x = sx - w;
int y = 0;
this->SetWindowPos(&CWnd::wndTopMost, x, y, w, h, SWP_SHOWWINDOW);

上記で画面の右端に幅50pxのウィンドウが表示されるようになりました。

AppBarの登録、登録解除

ウィンドウをディスプレイ端に配置したらAppBarの登録を行います。(システムにAppBarとしてウィンドウを登録するイメージ)

また、アプリケーション終了時にはAppBarの登録解除を行う必要があります。(登録解除しないと何も配置できない領域として残ってしまうため注意が必要です)

AppBarの登録

AppBarの登録を行うには、SHAppBarMessage関数で「ABM_NEW」「ABM_QUERYPOS」「ABM_SETPOS」を設定します。

void RegisterAppBar(HWND hWnd)
{
    APPBARDATA data;
    data.cbSize = sizeof(APPBARDATA);
    data.hWnd = hWnd;
    ::SHAppBarMessage(ABM_NEW, &data);

    data.uEdge = ABE_RIGHT;
    ::GetWindowRect(hWnd, &data.rc);
    ::SHAppBarMessage(ABM_QUERYPOS, &data);
    ::SHAppBarMessage(ABM_SETPOS, &data);
}

今回は右端に固定するためdata.uEdgeに「ABE_RIGHT」を指定していますが、固定する方向に合わせて適宜変更する必要があります。(配置した位置と指定された端が異なる場合固定されないことがあります)

AppBarの登録解除

AppBarの登録解除を行うには、SHAppBarMessage関数で「ABM_REMOVE」を設定します。

void UnRegisterAppBar(HWND hWnd)
{
    APPBARDATA data;
    data.cbSize = sizeof(APPBARDATA);
    data.hWnd = hWnd;
    ::SHAppBarMessage(ABM_REMOVE, &data);
}

アプリケーション終了時(WM_DESTROYやWM_CLOSE)に必ず実行されるようにします。

ウィンドウ属性の変更

ここまででウィンドウの固定はできそうなものですが、登録した領域からウィンドウが追い出されてしまいます。

WS_EX_APPWINDOW属性がついているとダメなようで、WS_EX_APPWINDOW属性を削除してWS_EX_TOOLWINDOW属性を付与します。

LONG style = ::GetWindowLong(hWnd, GWL_EXSTYLE);
style ^= WS_EX_APPWINDOW;
style |= WS_EX_TOOLWINDOW;
::SetWindowLong(hWnd, GWL_EXSTYLE, style);

ウィンドウ属性の変更はAppBarの登録前に実行する必要があります。

結果の確認

ここまでの処理(AppBarの登録削除以外)を初期化処理の中で実施することで、ディスプレイ(複数ある場合はメインディスプレイ)の右端にウィンドウが固定されます。(下図はわかりやすくするためにウィンドウの色を変えています、隣のエクスプローラは最大化表示しています)

アプリケーションを終了(何も変更していない場合ウィンドウをアクティブ状態にしてEscapeキーを押下)した際に画面の右端にまでエクスプローラが広がればAppBarの登録解除にも成功しています。

終わりに

MFCでタスクバーのようなアプリの作り方について解説しました。

普段はあまり使用することのない使い方かと思いますが、大型機械の組み込み画面など固定レイアウトで使用する画面で使うこともあるので、こういうこともできるんだと覚えておくと良いと思います。

この記事について誤っている点・不明な点などありましたらコメントまでお願いします。

コメント

タイトルとURLをコピーしました