第57章 ステータスバーを作る その1


今回は、ウィンドウにステータスバーをつけます。 ステータスバーというのは通常ウィンドウの下方に ある、細長いウィンドウです。目立たない存在ですが いろいろな情報を表示できて便利なものです。

ところで、ステータスバーとか、ツールバーなどは コモンコントロールといいます。 コモンコントロールはWindows95に含まれる コモンコントロールライブラリ(dll)で実現されます。 コモンコントロールを使うには commctrl.hをインクルードしなくてはいけません。 また、使用前にInitCommonControls()関数で初期化しなくてはいけません。

さらに、VC++では(多分他のコンパイラでも)Comctl32.libを プロジェクトに参加させなくてはいけません。 これが、前準備です。

ステータスバーを作るには、CreateWindowEX関数を使う方法と、 CreateStatusWindow関数を使う方法の2種類があります。 今回は前者の方を採用します。

ステータスバーの作り方手順 1.前準備(commctrl.hのインクルード、Comctl32.libの準備) 2.InitCommonControls関数の実行 3.CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD |..., 0, 0, 0, 0, hWnd, (HMENU)SB_ID, hInst, NULL); 4.SendMessage関数でステータスバーに指令を送る 5.WM_SIZEメッセージの処理

とこんな感じでやります。 まずは、CreateWindowEx関数の説明をします。

HWND CreateWindowEx( DWORD dwExStyle, // 拡張ウィンドウスタイル LPCTSTR lpClassName, // ウィンドウクラス名 LPCTSTR lpWindowName, // ウィンドウの名前 DWORD dwStyle, // ウィンドウスタイル int x, // X座標 int y, // Y座標 int nWidth, // 幅 int nHeight, // 高さ HWND hWndParent, // 親ウィンドウハンドル HMENU hMenu, // メニューハンドルまたは子供ウィンドウのID HINSTANCE hInstance, // インスタンスハンドル LPVOID lpParam // pointer to window-creation data );

となっています。ステータスバーを作るときはウィンドウクラス名を STATUSCLASSNAMEにします。

ウィンドウスタイルには必ずWS_CHILDを含ませます。 WS_VISIBLEを含ませるとあとでShowWindow関数を呼ばなくてもよいので 便利です。 SBS_SIZEGRIPを含ませるとサイズグリップがつきます。 サイズグリップとは ウィンドウの右下にある斜めの3本の線です。(こんな説明でわかるでしょうか)

また、ウィンドウの位置、大きさなどは すべて0にしておきます。

コントロールとしてのIDは適当に決めておきます。

つぎに、SendMessage関数でステータスバーに細かい指示を出します。 今回作るステータスバーは細かいパーツに分かれていない、シンプルなものです。 この場合、

SendMessage(ウィンドウハンドル, SB_SIMPLE, TRUE, 0L);

となります。

SB_SIMPLE wParam = (WPARAM) (BOOL) fSimple; lParam = 0;

fSimpleがTRUEのときはシンプルになります。

このステータスバーに何か文字を表示したいときは、

SB_SETTEXTメッセージを送ります。

SB_SETTEXT wParam = (WPARAM) iPart | uType; lParam = (LPARAM) (LPSTR) szText;

ステータスバーがシンプルの時はiPartは255になります。 シンプルでないときはパーツの番号が入ります。uTypeが0ならば テキストは、ウィンドウ平面より低い位置に表示されます。(要するにくぼんでいる) SBT_POPOUTならばウィンドウ平面より高い位置に表示されます。(浮き上がっている)

ステータスバーを非表示にしたいのなら、ShowWindow関数が使えます。

では、さっそく今回のサンプルプログラムを見てみましょう。 まず完成品の外観を見てください。

ステータスバーに時刻が刻々と表示されます。 メニューのオプションからステータスバーを表示したり 非表示にしたりできます。ステータスバーが表示されているときは メニューの「ステータスバー表示」の文字が薄くなっており 選択できなくなっていることに注意してください。

サイズグリップというのはステータスバーの右端にある斜線のことです。

// status01.rc // 自前で書く人は#include <windows.h> // と#include 自前のヘッダーファイル(IDM_END, IDM_ONなどを定義) // を忘れないでください。 ///////////////////////////////////////////////////////////////////////////// // // Menu // MYMENU MENU DISCARDABLE BEGIN POPUP "ファイル(&F)" BEGIN MENUITEM "終了(&X)", IDM_END END POPUP "オプション(&O)" BEGIN MENUITEM "ステータスバー表示", IDM_ON MENUITEM "ステータスバー消去", IDM_OFF END END

これは、ごく普通のメニューのリソース・スクリプトです。

// status.cpp #define STRICT #include <windows.h> #include <commctrl.h> //コモンコントロールのため必要 #include "resource.h" //自力でリソーススクリプトを書く人は自分のヘッダーファイル #define ID_STATUS 100 // #define ID_MYTIMER 32767 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); HWND CreateMyStatus(HWND, HINSTANCE); //ステータスバー作成関数 char szClassName[] = "status01"; //ウィンドウクラス HWND hStatus; //ステータスバーのウィンドウハンドル int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; if (!hPrevInst) { if (!InitApp(hCurInst)) return FALSE; } if (!InitInstance(hCurInst, nCmdShow)) { return FALSE; } while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }

#include <commctrl.h>を落とさないように注意してください。

//ウィンドウ・クラスの登録 BOOL InitApp(HINSTANCE hInst) { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; //プロシージャ名 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; //インスタンス wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = "MYMENU"; //メニュー名 wc.lpszClassName = (LPCSTR)szClassName; return (RegisterClass(&wc)); }

これはいつもと同じです。

//ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(szClassName, "猫でもわかるステータスパー",//タイトルバーにこの名前が表示されます WS_OVERLAPPEDWINDOW, //ウィンドウの種類 CW_USEDEFAULT, //X座標 CW_USEDEFAULT, //Y座標 CW_USEDEFAULT, //幅 CW_USEDEFAULT, //高さ NULL, //親ウィンドウのハンドル、親を作るときはNULL NULL, //メニューハンドル、クラスメニューを使うときはNULL hInst, //インスタンスハンドル NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; }

これも相変わらず同じです。

//ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; char str[256]; char *str_org = "ただ今%2d時%2d分%2d秒です"; SYSTEMTIME STime; static HINSTANCE hInst; hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); static HMENU hMenu; hMenu = GetMenu(hWnd); switch (msg) { case WM_CREATE: CreateMyStatus(hWnd, hInst); SetTimer(hWnd, ID_MYTIMER, 300, NULL); EnableMenuItem(hMenu, IDM_ON, MF_GRAYED); break; case WM_TIMER: GetLocalTime(&STime); wsprintf(str, str_org, STime.wHour, STime.wMinute, STime.wSecond); SendMessage(hStatus, SB_SETTEXT, 255 | 0, (WPARAM)(LPSTR)str); break; case WM_SIZE: SendMessage(hStatus, WM_SIZE, wp, lp); break; case WM_COMMAND: switch (LOWORD(wp)) { case IDM_END: SendMessage(hWnd, WM_CLOSE, 0L, 0L); break; case IDM_ON: ShowWindow(hStatus, SW_SHOW); EnableMenuItem(hMenu, IDM_ON, MF_GRAYED); EnableMenuItem(hMenu, IDM_OFF, MF_ENABLED); break; case IDM_OFF: ShowWindow(hStatus, SW_HIDE); EnableMenuItem(hMenu, IDM_OFF, MF_GRAYED); EnableMenuItem(hMenu, IDM_ON, MF_ENABLED); } break; case WM_CLOSE: id = MessageBox(hWnd, (LPCSTR)"終了してもよいですか", (LPCSTR)"終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { DestroyWindow(hWnd); } break; case WM_DESTROY: KillTimer(hWnd, ID_MYTIMER); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; }

SYSTEMTIME構造体や、GetLocalTime関数については第34章を 参照してください。

EnableMenuItem関数については第47章を参照してください。

ここでは、親ウィンドウが作られたらすぐにステータスバーを作ります。 そして、SetTimer関数を呼び出します。WM_TIMERメッセージを捕まえたら、 ステータスバーに時刻を表示します。

SendMessage(hStatus, SB_SETTEXT, 255 | 0, (WPARAM)(LPSTR)str);

の書き方に注意してください。ステータスバーがシンプルで、くぼんだ所に 表示するので3番目の引数は255 | 0となっています。

HWND CreateMyStatus(HWND hWnd, HINSTANCE hInst) { InitCommonControls(); //コモンコントロールのdllを初期化 hStatus = CreateWindowEx( 0, //拡張スタイル STATUSCLASSNAME, //ウィンドウクラス NULL, //タイトル WS_CHILD | SBARS_SIZEGRIP | CCS_BOTTOM | WS_VISIBLE, //ウィンドウスタイル //WS_VISIBLEを指定しないときは必ずShowWindow関数を呼ぶ 0, //X座標 0, //Y座標 0, //ウィンドウ幅 0, //高さ hWnd, //親ウィンドウ (HMENU)ID_STATUS, //ステータスバーのID hInst, //インスタンスハンドル NULL); SendMessage(hStatus, SB_SIMPLE, TRUE, 0L); return hStatus; }

ステータスバーを表示する自作関数です。

CreateWindowEx関数は引数がいっぱいあるので間違えないように注意してください。


[SDK Index] [総合Index] [Previous Chapter] [Next Chapter]

Update Jul/13/1997 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。