プログレスバーを持つ、ダイアログボックスを作成します。
プログレスバーが、0%から始まり、1秒おきに5%づつ増え、100%で止まるアプリケーションを作成します。
テキストの表示 - インコのWindowsSDK で作成したソースをもとに作成します。
ここでは、Reseditで作成する方法も説明します。
流れ
プログレスバーは、コモンコントロールのひとつです。コモンコントロールは他にも、ツリービューやリストビュー、ツールバーなどがあります。
コモンコントロールは、comctl32.dllというライブラリで提供されています。
コモンコントロールを使う場合は、下記1、2の両方を行って下さい。
1.commctrl.h をインクルード
windows.hをインクルードした後にインクルードしてください。
2.comctl32.lib を読み込む
WM_INITDIALOG
リストボックス - インコのWindowsSDK でも説明しましたが、WM_INITDIALOGは、ダイアログが作成されたときに、一度だけ発生するメッセージです。
1.InitCommonControls()でコモンコントロールの初期化
コモンコントロールを使う前にこの初期化が必要です。
2.プログレスバーを設定するのに、ウィンドウにメッセージを送る関数SendMessage()を使います。
lResult = SendMessage( HWND hWnd, // 送信先ウィンドウのハンドル UINT Msg, // メッセージ WPARAM wParam, // メッセージ特有のパラメータ1 LPARAM lParam // メッセージ特有のパラメータ2 );
2.1.PBM_SETRANGEメッセージで、プログレスバー範囲を設定。
コモンコントロールですので、commctrl.hをインクルードする必要があります。ライブラリにcomctl32.libを追加する必要があります。
lResult = SendMessage( (HWND) hWndControl, // プログレスバーのハンドル (UINT) PBM_SETRANGE, (WPARAM) 0, // 0固定 (LPARAM) MAKELPARAM(pb_min, pb_max) // プログレスバー範囲の最小値をLOWORD、最大値をHIWORD );
2.2.PBM_SETSTEPメッセージで、プログレスバー 1ステップの増分を設定します。
これもcommctrl.hをインクルードして、ライブラリにcomctl32.libを追加する必要があります。
lResult = SendMessage( (HWND) hWndControl, // プログレスバーのハンドル (UINT) PBM_SETSTEP, (WPARAM) pb_step, // 1ステップの増分 (LPARAM) 0, // 0固定 );
3.SetTimer()で、タイマをミリ秒単位でセット。
UINT_PTR SetTimer( HWND hWnd, // ウィンドウのハンドル UINT_PTR nIDEvent, // タイマのID UINT uElapse, // タイムアウト値(ミリ秒単位) TIMERPROC lpTimerFunc // TimerProcコールバック関数へのポインタ );
上記のlpTimerFuncがNULLの場合は、タイマがタイムアップするごとに、
WM_TIMERメッセージに対する処理が実行されます。
それ以外の場合は、タイマがタイムアップするごとに、
TimerProcコールバック関数(タイマプロシージャ)が実行されます。
タイムアップした時の処理を、WM_TIMERメッセージで処理するか、TimerProcコールバック関数を新たに作成して、そこで処理するかの違いです。
ここでは、WM_TIMERメッセージで処理します。
WM_TIMER
WM_TIMERメッセージは、セットされたタイマがタイムアップした場合に発生するメッセージです。
1.プログレスバーが100%に達したときに、タイマを止める関数 KillTimer() を実行します。
BOOL KillTimer( HWND hWnd, // ウィンドウのハンドル UINT_PTR nIDEvent // タイマのID );
2.PBM_STEPITメッセージで、プログレスバーを1ステップ増分。
lResult = SendMessage( (HWND) hWndControl, // プログレスバーのハンドル (UINT) PBM_STEPIT, (WPARAM) 0, // 0固定 (LPARAM) 0, // 0固定 );
3.現在のプログレスバー増分を変数strに格納。
_stprintf_s()は、tchar.hで定義されており、文字セットがunicodeの場合は、swprintf_s()になり、 文字セットがマルチバイトのときは、sprintf_sになります。
_stprintf_s(a, MAX_SIZE, format, [c・・・])
この_stprintf_s()は、数式などを文字列に変換するものです。
文字列a に、制御文字列formatで示す形式でセットします。
この制御文字列には、%d(10進数の整数)、%s(文字列)、%f(小数)といったフォーマット指定子を含めることができます。
MAX_SIZE は、文字列a が確保するバッファのサイズです。
swprintf_s、sprintf_sはそれぞれ、swprintf、sprintfのセキュリティが強化されたものです。
4.SetWindowText()で、変数strを表示。
SetWindowText()は、
エディット - インコのWindowsSDK
で紹介したSetDlgItemText()と同じ機能を持ちます。
BOOL SetWindowText( HWND hWnd, // ウィンドウのハンドル LPCTSTR lpString // セットする文字列 );
リソースファイル
1.プログレスバーを使用するため、commctrl.hをインクルード。
2.プログレスバー[PROGRESS_CLASS]を追加。
PROGRESS_CLASSの代わりに、"msctls_progress32"と記述することができます。「" "」を忘れないで下さい。
この場合は、リソースファイルで、commctrl.hをインクルードする必要はありません。
ただし、"msctls_progress32"と記述した場合でも、Cソースファイルでは、commctrl.hのインクルードが必要です。
CONTROL "", id, PROGRESS_CLASS, style, x0, y0, width, height
id | コントロールID |
style |
スタイル(要:commctrl.h) PBS_SMOOTH : スムーズ(Lunaスタイルでは変化なし) PBS_VERTICAL : 縦型のプログレスバー |
x0 | プログレスバー左上のx座標 |
y0 | プログレスバー左上のy座標 |
width | プログレスバーの幅 |
height | プログレスバーの高さ |
・Visual Studioのリソース ビュー、ResEditでの設定
ツールボックス(Toolbox)ウインドウの「Progress Bar」を選択すると、プログレスバーが作成できます。
「Static Text」は、テキストを挿入する際に使用します。
ソースコードの入力
ソースコードは下記のように入れてください。
#include <windows.h> #include <commctrl.h> #include <stdio.h> #include <tchar.h> #include "resource.h" #pragma comment(lib, "comctl32.lib") #define pb_step 5 #define pb_min 0 #define pb_max 100 UINT iProg; // 現在のプログレスバーの位置 // このコード モジュールに含まれる関数の宣言を転送します: BOOL CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow ) { DialogBox(hInstance, TEXT("DIALOG_BOX"), NULL, DialogProc); return 0; } BOOL CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HWND hProg; TCHAR str[10]; hProg = GetDlgItem(hWnd, IDC_PROGRESS1); switch (msg) { case WM_INITDIALOG: InitCommonControls(); SendMessage(hProg, PBM_SETRANGE, (WPARAM)0, MAKELPARAM(pb_min, pb_max)); SendMessage(hProg, PBM_SETSTEP, (WPARAM)pb_step, 0); SetTimer(hWnd,IDC_TIMER, 1000, NULL); /*1000[ms]タイマーイベント*/; break; case WM_TIMER: iProg += pb_step; if(iProg >= 100) { KillTimer(hWnd, IDC_TIMER); } SendMessage(GetDlgItem(hWnd, IDC_PROGRESS1), PBM_STEPIT, 0, 0); _stprintf_s(str, 10, TEXT("%d %"), iProg); SetWindowText(GetDlgItem(hWnd, IDC_STATIC1), (LPCTSTR)str); break; case WM_CLOSE: KillTimer(hWnd, IDC_TIMER); EndDialog(hWnd, IDOK); break; } return FALSE; }
#define IDC_PROGRESS1 500
#define IDC_TIMER 1000
#define IDC_STATIC1 1
#ifndef IDC_STATIC
#define IDC_STATIC -1
#endif
Reseditで作成した場合は、これとは異なるソースコードになります。
#include "resource.h" #include <commctrl.h> ///////////////////////////////////////////////////////////////////////////// // // ダイアログ // DIALOG_BOX DIALOG 0, 0, 170, 62 FONT 9, "MS UI Gothic" CAPTION "ダイアログ" BEGIN CONTROL "", IDC_PROGRESS1, PROGRESS_CLASS, 0, 29, 38, 123, 14 LTEXT "%", IDC_STATIC1, 88, 16, 29, 15 END
Reseditで作成した場合は、これとは異なるソースコードになります。