第11章 もう少し気の利いたプログラム


さて、API関数の中には、SetWindowText関数というものが あります。このプロトタイプは、

BOOL SetWindowText( HWND hWnd, // ウィンドウハンドル LPCTSTR lpString // 文字列のアドレス );

となっています。使い方は簡単です。ウィンドウハンドルと 表示したい文字列を指定するだけです。 これで何をするかというと タイトルバーの文字列を変更するのです。 ともかく、この関数を呼ぶだけでタイトルバーの 文字列を変更することができます。 クライアント領域に描画するわけではないので BeginPaint関数なんかも呼ばなくてOKです。


では、この関数を使ってタイトルバーに 現在の時刻を表示するようにしてみましょう。 クライアント領域は、前章と同じです。 では、前回のtimer.cppの一部を変更してみます。 といっても、プロシージャのWM_TIMERメッセージの所に 1行追加するだけです。

case WM_TIMER: GetTimeStr(); SetWindowText(hWnd, (LPCSTR)time_str); InvalidateRect(hWnd, NULL, FALSE); break;

たったこれだけの変更ですが、どうなったか実行してみましょう。
タイトルバーに、現在の時刻が刻々と表示されていますね。 それでは、これを最小化ボタンで小さくしてみましょう。 Windows95の場合、タスクバーに表示されますね。 タイトルバーに表示する文字列を「*時*分*秒」だけに して、最小化するとタスクバーに刻々と時間を刻む ちょっとしたアクセサリーの出来上がりです。

では、そのようにプログラムを変更しましょう。 クライアント領域に表示する必要はないので、 その部分を削除します。また、CreateWindow関数の なかで、タイトルバーに表示される部分はNULLでいいですね。 また、クラスメニューも不要ですね。

//ウィンドウ・クラスの登録 BOOLはTRUEかFALSEしか返さないの意味 BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName) { 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 = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL/*"TIMERMENU"*/; //メニュー名 wc.lpszClassName = (LPCSTR)szClassName; return (RegisterClass(&wc)); }

メニューはないのでNULLに変更しました。

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

2番目の引数をNULLにしました。ウィンドウの種類は、 WS_CAPTION | WS_SYSMENUとしました。ウィンドウを表示する必要はないので WS_OVERLAPPEDWINDOWにする必要はありません。タイトルバーと、システムメニューボタン があればいいだけですね。 ウィンドウの幅、高さを0にしました。実際は小さい長方形となります。(やってみればわかる) ShowWindow関数の2番目の引数をSW_MINIMIZEに変更しました。

次は、プロシージャ部分です。

//ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; switch (msg) { case WM_CREATE: if(SetTimer(hWnd, ID_MYTIMER, 1000, NULL) == 0) { MessageBox(hWnd, (LPCSTR)"タイマー失敗!", (LPCSTR)"失敗", MB_OK | MB_ICONEXCLAMATION); } break; case WM_TIMER: GetTimeStr(); SetWindowText(hWnd, (LPCSTR)time_str); break; case WM_CLOSE: id = MessageBox(hWnd, (LPCSTR)"終了してもよいですか", (LPCSTR)"終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { if(KillTimer(hWnd, ID_MYTIMER) == TRUE) { MessageBox(hWnd, (LPCSTR)"タイマーを殺しました!", (LPCSTR)"タイマー削除の成功", MB_OK | MB_ICONEXCLAMATION); } DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; }

前章より、だいぶん短くなっていますね。(クライアント領域への描画がない) 最後に、自作関数のGetTimeStrです。

int GetTimeStr(void) { char *str_org = "%2d時%2d分%2d秒"; time_t long_time; struct tm *now_time; time(&long_time); now_time = localtime(&long_time); sprintf(time_str, str_org, now_time->tm_hour, now_time->tm_min, now_time->tm_sec); return 0; }

これは、説明の必要はないですね。では、実行してみましょう。

タスクバーで黙々と時間を刻み続けます。そういえば、 こういったフリー・ソフトをどこかで見かけたことがあります。 多分、今みたいにして作ったに違いありません。 (と、筆者は勝手に考えています)こういったちょっとした プログラムならSDKで充分に作れます。


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

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