ステータスバー
ステータスバーは、ウィンドウの下部に表示される、情報を表示するための棒状のコントロールです。
ツールバーと同じくコモンコントロールの一種です。
コモンコントロールについてはツールバーのページを参照してください。
INITCOMMONCONTROLSEX構造体のdwICC
メンバは、ツールバーと同じくICC_BAR_CLASSES
を指定することで使用できます。
ステータスバーの作成
ステータスバーはCreateWindowEx関数で、ウィンドウスタイルにSTATUSCLASSNAME
という定数を指定することで作成できます。
この定数の中身は"msctls_statusbar32"
という文字列です。
ウィンドウスタイルはWS_CHILD
とWS_VISIBLE
のほか、CCS_BOTTOM
とSBARS_SIZEGRIP
の二つも指定します。
CCS_BOTTOM
はコモンコントロールに共通のウィンドウスタイルで、ウィンドウの下部にコントロールを表示するという意味です。
位置指定のスタイルを何も指定しない場合はウィンドウの上部に表示されます。
(CCS_TOP
を指定するのと同じ)
SBARS_SIZEGRIP
は、ステータスバーの右下にウィンドウサイズ調整のグリップが表示されます。
このスタイルを指定しなくてもウィンドウサイズは調整できますが、マウス入力を受け付ける領域が少し広くなり操作しやすくなります。
HWND hStatusbar = CreateWindowEx(0, STATUSCLASSNAME, NULL,
WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
0, 0, 0, 0,
hWnd, NULL, hInst, NULL);
SB_SIMPLEメッセージ
ステータスバーは、単純なテキストひとつだけを表示する簡易モード(シンプルモード)と、いくつかのパーツに分割して異なる情報を同時に表示できる分割モードがあります。
モードはステータスバーにSB_SIMPLE
メッセージを送信することで切り替えることができます。
WPARAMにTRUE
を指定すると簡易モード、FALSE
を指定すると分割モードに設定されます。
LPARAMは使用しないので0を指定します。
ここでは簡易モードに設定します。
SendMessage(hStatusbar, SB_SIMPLE, TRUE, 0);
SB_SETTEXTメッセージ
ステータスバーに文字列を設定するにはSB_SETTEXT
メッセージを使用します。
WPARAMは、下位ワードの下位バイト(LOBYTE、下位ワードではない)に、テキストを設定するパーツのインデックス(番号)を指定します。
簡易モードの場合、ここにはSB_SIMPLEID
という定数を指定します。
下位ワードの上位バイト(HIBYTE)には、ステータスバーの描画方法を示す以下の定数のいずれかを指定します。
WPARAMの上位ワードは無視されます。
定数 | 説明 |
---|---|
0 | 窪んだ罫線 ウィンドウ領域より低く見える |
SBT_NOBORDERS | 罫線なし |
SBT_OWNERDRAW | オーナードロー 簡易モードでは使用できない |
SBT_POPOUT | 膨らんだ罫線 ウィンドウ領域より高く見える |
SBT_RTLREADING | テキスト方向を親ウィンドウとは逆にする |
SBT_NOTABPARSING | タブ文字を無視する |
LPARAMには表示したい文字列を指定します。
WPARAMの指定がなんだかややこしく見えますが、それぞれの値をビットOR演算子でつなげるだけです。
SendMessage(
hStatusbar,
SB_SETTEXT,
SB_SIMPLEID | SBT_NOBORDERS,
(LPARAM)L"表示したいテキスト");
定数SB_SIMPLEID
は「0xff」(255)と定義されています。
パーツ数の指定は1バイトの情報で行うので、パーツは最大で255個までということになります。
上表で説明した描画指定の定数は、下位バイトは全て0で上位バイトに値が設定されています。
例えば定数SBT_NOBORDERS
は「0x0100」と定義されています。
「0x00ff」と「0x0100」をビットOR演算すれば「0x01ff」ですから、互いに値が干渉しないように定義されています。
正式に定義する場合はLOBYTE
マクロとHIBYTE
マクロ、およびMAKEWORD
マクロを使用して以下のように記述します。
(得られる値は同じです)
SendMessage(
hStatusbar,
SB_SETTEXT,
MAKEWORD(LOBYTE(SB_SIMPLEID), HIBYTE(SBT_NOBORDERS)),
(LPARAM)L"テキスト");
WM_SIZEメッセージ
ここまでの手順でステータスバーにテキストが表示されますが、ウィンドウサイズを変更したときにステータスバーのサイズは自動で変更されません。
サイズの調整は親ウィンドウでWM_SIZEメッセージが処理されるとき、ステータスバーにWM_SIZE
メッセージを送信します。
パラメーター(WPARAM、LPARAM)はそのまま渡します。
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hStatusbar;
switch (message)
{
case WM_SIZE:
SendMessage(hStatusbar, WM_SIZE, wParam, lParam);
break;
//以降省略
サンプルコード
全体のサンプルコードです。
#pragma comment(lib, "Comctl32.lib")
#include <windows.h>
#include <strsafe.h>
#include <commctrl.h>
//ウィンドウの生成等は省略
//ステータスバーを作成する
HWND CreateStatusbar(HWND hWnd)
{
//コモンコントロールの初期化
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_BAR_CLASSES;
InitCommonControlsEx(&icc);
//ステータスバー作成
HWND hStatusbar = CreateWindowEx(0, STATUSCLASSNAME, NULL,
WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
0, 0, 0, 0,
hWnd, NULL, hInst, NULL);
//簡易モードを設定
SendMessage(hStatusbar, SB_SIMPLE, TRUE, 0);
return hStatusbar;
}
#define BUFFERSIZE 256
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hStatusbar;
static int clickCount;
static WCHAR text[BUFFERSIZE];
switch (message)
{
case WM_CREATE: //ウィンドウの作成
//ステータスバー作成
hStatusbar = CreateStatusbar(hWnd);
//ステータスバーにテキストを設定
SendMessage(hStatusbar, SB_SETTEXT, SB_SIMPLEID | 0, (LPARAM)L"クリック数: 0");
break;
case WM_SIZE: //ウィンドウサイズ変更
SendMessage(hStatusbar, WM_SIZE, wParam, lParam);
break;
case WM_LBUTTONUP:
StringCchPrintf(text, BUFFERSIZE, L"クリック数: %d", ++clickCount);
SendMessage(hStatusbar, SB_SETTEXT, SB_SIMPLEID | 0, (LPARAM)text);
break;
case WM_RBUTTONUP:
clickCount = 0;
SendMessage(hStatusbar, SB_SETTEXT, SB_SIMPLEID | 0, (LPARAM)L"クリック数: 0");
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
このコードはウィンドウ上をクリックした回数をステータスバーに表示します。
右クリックで回数をリセットします。
分割モード
ステータスバーの領域を分割するにはSB_SIMPLEメッセージのWPARAMにFALSE
を指定して送信し、分割モードに設定します。
SB_SETPARTS
次に、SB_SETPARTS
メッセージでパーツ数とパーツサイズを設定します。
WPARAMはパーツ数を指定します。
パーツ数は255以下である必要があります。
LPARAMは各パーツのサイズを示す整数値の配列を指定します。
配列の要素数はパーツと同じだけ用意し、要素の数値はパーツの右端の位置を意味します。
要素に-1
を指定すると、右端位置はウィンドウの右端に設定されます。
//分割モードを設定
SendMessage(hStatusbar, SB_SIMPLE, FALSE, 0);
//パーツ数の指定
int sbSizes[3] = { 100, 250, -1 };
SendMessage(hStatusbar, SB_SETPARTS, 3, (LPARAM)sbSizes);
この例では3つのパーツに分割しています。
サイズは左から「100」「150」「ウィンドウサイズ - 250」となり、一番右のパーツだけ可変サイズになります。
最後に各パーツに文字列を設定します。
SB_SETTEXTメッセージのWPARAMで文字列を設定するパーツのインデックスを指定します。
SendMessage(hStatusbar, SB_SETTEXT, 0 | 0, (LPARAM)L"左端");
SendMessage(hStatusbar, SB_SETTEXT, 1 | 0, (LPARAM)L"真ん中");
SendMessage(hStatusbar, SB_SETTEXT, 2 | 0, (LPARAM)L"右端");
パーツ数を変更すると設定していたテキストは消去されるので注意してください。
(パーツのサイズだけを変更する場合は消去されません)
サンプルコード
全体のサンプルコードです。
#pragma comment(lib, "Comctl32.lib")
#include <windows.h>
#include <strsafe.h>
#include <commctrl.h>
//ウィンドウの生成等は省略
//ステータスバーを作成する
HWND CreateStatusbar(HWND hWnd)
{
//コモンコントロールの初期化
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_BAR_CLASSES;
InitCommonControlsEx(&icc);
//ステータスバー作成
HWND hStatusbar = CreateWindowEx(0, STATUSCLASSNAME, NULL,
WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
0, 0, 0, 0,
hWnd, NULL, hInst, NULL);
//分割モードを設定
SendMessage(hStatusbar, SB_SIMPLE, FALSE, 0);
//パーツ数の指定
//実際の位置はWM_SIZEメッセージで処理する
int sbSizes[3] = { 0, 0, 0 };
SendMessage(hStatusbar, SB_SETPARTS, 3, (LPARAM)sbSizes);
return hStatusbar;
}
#define BUFFERSIZE 256
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hStatusbar;
static int clickCount;
static WCHAR text[BUFFERSIZE];
int sbSizes[3];
switch (message)
{
case WM_CREATE: //ウィンドウの作成
//ステータスバー作成
hStatusbar = CreateStatusbar(hWnd);
//ステータスバーにテキストを設定
SendMessage(hStatusbar, SB_SETTEXT, 0 | 0, (LPARAM)L"左端");
SendMessage(hStatusbar, SB_SETTEXT, 1 | 0, (LPARAM)L"真ん中");
SendMessage(hStatusbar, SB_SETTEXT, 2 | 0, (LPARAM)L"右端");
break;
case WM_SIZE: //ウィンドウサイズ変更
SendMessage(hStatusbar, WM_SIZE, wParam, lParam);
//パーツの位置を設定
sbSizes[0] = LOWORD(lParam) - 200;
sbSizes[1] = LOWORD(lParam) - 100;;
sbSizes[2] = -1;
SendMessage(hStatusbar, SB_SETPARTS, 3, (LPARAM)sbSizes);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
ウィンドウサイズ変更時にステータスバーの各パーツのサイズも調整したいので、WM_SIZE
メッセージ処理内でSB_SETPARTS
メッセージを送信しています。
WM_SIZE
メッセージでは、LPARAMの下位ワードがウィンドウの横幅なので、この値を元に各パーツのサイズを決定します。
このコードでは左端パーツサイズは可変、真ん中と右端パーツのサイズを「100」にしています。