スタティック
テキストを表示するボックス
ウィンドウ内に表示されるボタンやテキスト、リストボックスやテキストボックスといった、ユーザーと対話するための GUI 部品のことを Wisdows の世界ではコントロールと呼んでいます。
コントロールは自分で作ることもできますが、多くのアプリケーションで共通して利用される機能に関しては標準コントロールとして用意されています。テキストやボタンなどは Windows が提供する標準コントロールを使うことで簡単に表示できます。ウィンドウクラスの登録や、ウィンドウプロシージャの作成は不要です。
コントロールの実体は CreateWindow() 関数または CreateWindowEx() 関数で生成される HWND 型のハンドルです。つまり、ボタンなどのコントロールもウィンドウの一種であり、ウィンドウと同じように扱うことができます。
この場では、最も単純なテキストを表示する機能だけを持つスタティックと呼ばれるコントロールを紹介します。このコントロールは、一般にラベルと呼ばれるコントロールに等しく、主な機能はテキストの表示です。ユーザーの入力には反応しません。
標準コントロールのウィンドウクラスは事前に用意されており、定められた文字列をウィンドウクラス名に指定してウィンドウを生成します。スタティックコントロールを作成するには STATIC という文字列をウィンドウクラス名に指定します。
ウィンドウは親子関係を結ぶことができ、子ウィンドウは親ウィンドウの内部に表示されます。コントロールをウィンドウ内に貼り付けるには、CreaweWindow() 関数または CreateWindowEx() 関数の hWndParent パラメータに親となるウィンドウのハンドルを指定します。また、他のウィンドウの子ウィンドウになる場合は WS_CHILD をスタイルに設定します。
CreateWindowEx( WS_EX_LEFT, TEXT("STATIC"), TEXT("Stand by Ready!!"), WS_CHILD | WS_VISIBLE, 0, 0, 400, 100, hWndParent, NULL, hInstance, NULL );
上記の CreateWindowEx() 関数で生成されたウィンドウは、指定した親ウィンドウの原点から幅 400 ピクセル、高さ 100 ピクセルのスタティックコントロールを表します。ウィンドウクラスに STATIC という文字列を設定している点に注目してください。
通常のアプリケーションウィンドウであれば、タイトルバーやメニューバー、サイズ変更境界線などの枠を持ちます。これらを除外した、内側のコンテンツを表示する領域の左上隅が子ウィンドウの原点となります。この領域のことをクライアント領域と呼びます。コンテンツは、クライアント領域内で表示することになります。
子ウィンドウの座標は、親ウィンドウの作業領域からの相対座標となります。
親ウィンドウが移動すれば、子ウィンドウも相対的に動きます。ウィンドウ内のコンテンツは、スクリーン上のウィンドウの位置を意識する必要はなく、常に親ウィンドウのクライアント座標を基点にデザインできます。
#include <windows.h> #define WINDOWS_CLASS_NAME TEXT("WisdomSoft.Sample.Window") LRESULT CALLBACK SampleWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hwnd , uMsg , wParam , lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND window, label; WNDCLASSEX wcx; int returnCode = 0; ULONG p; wcx.cbSize = sizeof(WNDCLASSEX); wcx.style = CS_HREDRAW | CS_VREDRAW; wcx.lpfnWndProc = SampleWindowProc; wcx.cbClsExtra = 0; wcx.cbWndExtra = 0; wcx.hInstance = hInstance; wcx.hIcon = NULL; wcx.hCursor = NULL; wcx.hbrBackground = (HBRUSH)COLOR_BACKGROUND + 1; wcx.lpszMenuName = NULL; wcx.lpszClassName = WINDOWS_CLASS_NAME; wcx.hIconSm = NULL; if (!RegisterClassEx(&wcx)) { OutputDebugString(TEXT("Error: ウィンドウクラスの登録ができません。\n")); return 0; } window = CreateWindowEx( WS_EX_LEFT, WINDOWS_CLASS_NAME, TEXT("Window Title"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); if (!window) { OutputDebugString(TEXT("Error: ウィンドウを作成できません。\n")); return 0; } label = CreateWindowEx( WS_EX_LEFT, TEXT("STATIC"), TEXT("Stand by Ready!!"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 400, 100, window, NULL, hInstance, NULL ); if (!label) { OutputDebugString(TEXT("Error: コントロールを作成できません。\n")); return 0; } while(TRUE) { MSG msg; int r = GetMessage(&msg, NULL, 0, 0); if (r > 0) DispatchMessage(&msg); else if(r == -1) { OutputDebugString(TEXT("Error: メッセージの取得に失敗しました。\n")); break; } else { returnCode = msg.wParam; break; } } return returnCode; }
コード1はスタティックコントロールを生成し、アプリケーションウィンドウの子ウィンドウとして設定しています。実行結果のように、ウィンドウのテキストとして設定した文字列がコントロール上に表示されます。