スタティックコントロール

スタティックコントロールは「単純に表示するだけ」のものを描画するためのコントロールです。
クリックしてもボタンのようにイベントは発生しません。
主にテキストや画像を描画します。

コントロールの作成の基本的なことはボタンコントロールの項を参照してください。

スタティックコントロールの作成

スタティックコントロールはSTATICクラスで作成します。


#define IDC_STATIC -1

CreateWindow(
	L"STATIC", L"スタティックコントロールです。",
	WS_CHILD | WS_VISIBLE,
	10, 10, 200, 40,
	hWnd, (HMENU)IDC_STATIC, hInst, NULL);

スタティックコントロールの作成

スタティックコントロールは既定ではテキストを描画します。
改行文字やタブ文字も使用可能で、テキストは右端で折り返されます。

クリック等の処理は行わないので、子ウィンドウIDは全てのスタティックコントロールで共通で問題ありません。
ここでは「-1」を指定しています。

テキストの取得や変更が必要な場合は、ウィンドウハンドルを取得した上でSendMessage関数で行うことができます。

スタティックコントロールのスタイル

スタティックコントロールは以下のスタイルが適用できます。

定数 説明
SS_LEFT テキストの左揃え。
(既定)
SS_CENTER テキストの中央揃え。
SS_RIGHT テキストの右揃え。
SS_SIMPLE テキストの左揃え。
テキストサイズに合わせてコントロールサイズが自動で縮む。
改行文字やタブ文字などは使用できない。
SS_LEFTNOWORDWRAP テキストの左揃え。
改行文字やタブ文字は使用できるが、右端で自動折り返しされない。
定数 説明
SS_BLACKRECT 矩形をウィンドウ枠の色で塗りつぶす。
(既定では黒)
SS_GRAYRECT 矩形をスクリーンの背景色で塗りつぶす。
(既定ではグレー)
SS_WHITERECT 矩形をウィンドウの背景色で塗りつぶす。
(既定では白)
SS_BLACKFRAME 枠をウィンドウ枠の色にする。
(既定では黒)
SS_GRAYFRAME 枠をスクリーンの背景色にする。
(既定ではグレー)
SS_WHITEFRAME 枠をウィンドウの背景色にする。
(既定では白)
SS_SUNKEN 境界線を窪ませる。
定数 説明
SS_ICON アイコンの表示。
SS_BITMAP ビットマップの表示。
SS_REALSIZECONTROL コントロールのサイズに合わせてビットマップを拡大/縮小する。
SS_REALSIZEIMAGE 画像の原寸サイズに合わせてコントロールを拡大/縮小する。
SS_CENTERIMAGE 画像をコントロールの中央に配置する。
一行のテキストが表示されている場合は垂直方向の中央に配置する。
SS_RIGHTJUST 画像位置を右下隅にする。
定数 説明
SS_EDITCONTROL 複数行エディットコントロールと同じになるようにテキストを描画する。
平均文字幅がエディットコントロールと同じになる。
部分的に表示される最後の行は表示されない。
SS_ENDELLIPSIS 矩形領域に対してテキストが長すぎる場合、はみ出す部分がテキストの末尾であれば領域に収まるようにテキストの末尾を省略記号(...)に置き換えて表示する。
末尾以外の部分がはみ出す場合は省略記号なしで切り取られる。
右端での折り返しはされず、一行になるように強制される。
SS_PATHELLIPSIS 矩形領域に対してテキストが長すぎる場合、領域に収まるようにテキストの途中を省略記号(...)に置き換えて表示する。
\記号を含む文字列でないと効果がないのかもしれない。
右端での折り返しはされず、一行になるように強制される。
SS_WORDELLIPSIS 矩形領域に対してテキストが長すぎる場合、領域に収まるようにテキストの末尾を省略記号(...)に置き換えて表示する。
右端での折り返しはされず、一行になるように強制される。
定数 説明
SS_NOTIFY コントロールのクリック/ダブルクリック時に親ウィンドウにWM_COMMANDメッセージを送信する。
WPARAMの下位ワードにはSTN_CLICKEDSTN_DBLCLKSTN_DISABLESTN_ENABLEの通知コードが格納される。
SS_OWNERDRAW オーナードロースタティックコントロール。
コントロール内の描画をプログラマ自身が行う。

テキストの表示機能についてはDrawText関数と共通点が多いのでそちらも参考にしてください。

SS_NOTIFYスタイルを使用すると、スタティックコントロールのクリック等で親ウィンドウにWM_COMMANDメッセージが送信されるようになります。
WPARAMの上位ワードにはそれぞれの操作を表す通知コードが格納されています。
後はボタンなどと同じように処理をすれば良いのですが、子ウィンドウIDは他のコントロールと識別できるように1以上の独立した値を割り振っておく必要があります。

画像の表示

スタティックコントロールに画像を表示するにはSS_BITMAP(またはSS_ICON)スタイルを設定した上で、SendMessage関数STM_SETIMAGEメッセージを送信します。
WPARAMにはIMAGE_BITMAP(またはIMAGE_ICON)を指定します。
LPARAMには画像のハンドルを指定します。

メッセージが異なる以外はボタンに画像を表示する場合と同じ手順です。


#include <windows.h>
#include "resource.h"

//ウィンドウの生成等は省略

#define IDC_STATIC -1

//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HBITMAP hBmp;
	HWND h;

	switch (message)
	{
	case WM_CREATE: //ウィンドウ作成
		//スタティックコントロールの作成
		h = CreateWindow(
			L"STATIC", NULL,
			WS_CHILD | WS_VISIBLE | SS_BITMAP | SS_REALSIZECONTROL,
			10, 10, 60, 60,
			hWnd, (HMENU)IDC_STATIC, hInst, NULL);
		
		hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
		SendMessage(h, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmp);
		break;

	case WM_DESTROY: //ウィンドウの破棄
		DeleteObject(hBmp);
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

既定では画像のサイズに合わせてスタティックコントロールが拡大/縮小します。
それで都合が悪い場合はSS_REALSIZECONTROLスタイルを指定すると、スタティックコントロールのサイズにあわせて画像が拡大/縮小します。

描画のカスタマイズ

スタティックコントロールは、内容が描画される直前に親ウィンドウに対してWM_CTLCOLORSTATICメッセージを送信します。
このメッセージ内ではスタティックコントロールの描画をカスタマイズすることができます。

WM_CTLCOLORSTATICメッセージのWPARAMは描画されようとしているスタティックコントロールのデバイスコンテキストが格納されています。
LPARAMにはスタティックコントロールのウィンドウハンドルが格納されています。

デバイスコンテキストが取得できるので、これを通して文字色や背景色、フォントなどを変更することができます。

なお、ウィンドウプロシージャでメッセージを処理した場合、通常は「0」を返す決まりですが、WM_CTLCOLORSTATICメッセージを処理した場合はコントロールの背景の描画に使用するブラシを返す必要があります。


#include <windows.h>

//ウィンドウの生成等は省略

#define IDC_STATIC 1000

//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HWND hStatic1, hStatic2, hStatic3, hStatic4;
	static HFONT hFont;

	switch (message)
	{
	case WM_CREATE: //ウィンドウ作成
		hStatic1 = CreateWindow(
			L"STATIC", L"スタティックコントロールです。",
			WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE,
			10, 10, 280, 30,
			hWnd, (HMENU)IDC_STATIC, hInst, NULL);
		
		hStatic2 = CreateWindow(
			L"STATIC", L"スタティックコントロールです。",
			WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE,
			10, 50, 280, 30,
			hWnd, (HMENU)IDC_STATIC, hInst, NULL);

		hStatic3 = CreateWindow(
			L"STATIC", L"スタティックコントロールです。",
			WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE,
			10, 90, 280, 30,
			hWnd, (HMENU)IDC_STATIC, hInst, NULL);

		hStatic4 = CreateWindow(
			L"STATIC", L"スタティックコントロールです。",
			WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE,
			10, 130, 280, 30,
			hWnd, (HMENU)IDC_STATIC, hInst, NULL);

		//フォントを作成
		hFont = CreateFont(16, 0, 0, 0,
			FW_BOLD, FALSE, FALSE, 0,
			SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS,
			CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_DONTCARE,
			L"MS 明朝");

	case WM_CTLCOLORSTATIC:
		if ((HWND)lParam == hStatic1) {
			//背景色を赤に設定
			SetDCBrushColor((HDC)wParam, RGB(255, 0, 0));
			return (LRESULT)GetStockObject(DC_BRUSH);
		}
		else if ((HWND)lParam == hStatic2) {
			//背景色を赤に設定
			//テキストの背景モードを透過に設定
			SetDCBrushColor((HDC)wParam, RGB(255, 0, 0));
			SetBkMode((HDC)wParam, TRANSPARENT);
			return (LRESULT)GetStockObject(DC_BRUSH);
		}
		else if ((HWND)lParam == hStatic3) {
			//背景色と文字色を変更して
			//白抜き文字にする
			SetDCBrushColor((HDC)wParam, RGB(0, 0, 0));
			SetBkMode((HDC)wParam, TRANSPARENT);
			SetTextColor((HDC)wParam, RGB(255, 255, 255));
			return (LRESULT)GetStockObject(DC_BRUSH);
		}
		else if ((HWND)lParam == hStatic4) {
			//フォントを変更
			SelectObject((HDC)wParam, hFont);
			return (LRESULT)NULL;
		}
		break;

	case WM_DESTROY: //ウィンドウの破棄
		DeleteObject(hFont);
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

上から順に「背景色の変更」「背景色とテキスト背景色の変更(透過)」「背景色とテキスト背景色とテキスト色の変更」「フォントの変更」を行っています。
スタティックコントロールの描画のカスタマイズ