第197章 新しいプログレスバー


プログレスバーについてはすでに第72章で解説しています。 その後IEのバージョンアップに伴うComctl32.dllの更新(Ver4.70以降)により 新しいスタイル等が加わりました。



今回作るプログラムでは親ウィンドウのメニューから「オプション」 「プログレスバーを出す」を選択すると左の図のようなダイアログボックスが 出現します。

バーの色とか背景を設定できます(Ver4.71以降)。
また、縦型に表示できます(Ver4.70以降)。
さらに、スムース表示(左側のプログレスバー)ができるようになりました(Ver4.70以降)。

今回は、「CLICK!」ボタンを押すと少しずつバーが伸びで100回クリックすると 満杯になる(それ以上押しても増えない)プログレスバーを作ります。 これだけでは簡単過ぎるのでリアルタイムに親ウィンドウのクライアント領域にもクリック数を 表示させます。

// newprog01.rcの一部 ///////////////////////////////////////////////////////////////////////////// // // Menu // MYMENU MENU DISCARDABLE BEGIN POPUP "ファイル(&F)" BEGIN MENUITEM "終了(&X)", IDM_END END POPUP "オプション(&O)" BEGIN MENUITEM "プログレスバーを出す(&P)", IDM_PROG END END ///////////////////////////////////////////////////////////////////////////// // // Dialog // MYDLG DIALOGEX 0, 0, 66, 165 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "プログレスバー" FONT 9, "MS Pゴシック" BEGIN DEFPUSHBUTTON "CLICK!",IDOK,7,124,50,14 PUSHBUTTON "CLEAR",IDC_CLEAR,7,143,50,14 CONTROL "Progress1",IDC_PROGRESS1,"msctls_progress32", PBS_VERTICAL | PBS_SMOOTH | WS_BORDER,7,7,18,97 CONTROL "Progress2",IDC_PROGRESS2,"msctls_progress32", PBS_VERTICAL | WS_BORDER,38,7,18,97 LTEXT "Static",IDC_STATIC1,7,111,19,10,0,WS_EX_RIGHT LTEXT "Static",IDC_STATIC2,34,111,19,10,0,WS_EX_RIGHT END

新しいプログレスバーのスタイルPBS_VERTICAL, PBS_SMOOTHに注意して下さい。 実際にはリソース・エディタでプログレスバーのプロパティの「垂直方向」「スムーズ」 にチェックをつけるだけです。

// newprog1.cpp #ifndef STRICT #define STRICT #endif #include <windows.h> #include <commctrl.h> #include "resource.h" #define BAR_MAX 100 #define WM_MYMSG WM_USER LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MyDlgProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); char szClassName[] = "newprog1"; //ウィンドウクラス HINSTANCE hInst;

いつもと同じですがWM_MYMSGを定義している点に注意して下さい。 あとで、ダイアログボックスから親ウィンドウにデータを送る時に使います。

また、プログレスバーをリソースエディタで作った場合comctl32.libを リンクしなくてもよいようです。

int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; hInst = hCurInst; if (!InitApp(hCurInst)) return FALSE; if (!InitInstance(hCurInst, nCmdShow)) return FALSE; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //ウィンドウ・クラスの登録 ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); 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; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); return (RegisterClassEx(&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; INITCOMMONCONTROLSEX ic; HDC hdc; PAINTSTRUCT ps; static TCHAR szStr[256]; static int nCount; switch (msg) { case WM_CREATE: ic.dwSize = sizeof(INITCOMMONCONTROLSEX); ic.dwICC = ICC_PROGRESS_CLASS; break; case WM_MYMSG: nCount = (int)lp; InvalidateRect(hWnd, NULL, TRUE); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); wsprintf(szStr, "現在のカウント=%d", nCount); TextOut(hdc, 5, 5, szStr, lstrlen(szStr)); EndPaint(hWnd, &ps); break; case WM_COMMAND: switch (LOWORD(wp)) { case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0); break; case IDM_PROG: DialogBox(hInst, "MYDLG", hWnd, (DLGPROC)MyDlgProc); break; } break; case WM_CLOSE: id = MessageBox(hWnd, "終了してもよいですか", "終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }

WM_CREATEメッセージが来たらコモンコントロールを初期化します。 プログレスバーの場合INITCOMMONCONTROLSEX構造体のdwICCメンバは ICC_PROGRESS_CLASSに設定します。

自作メッセージWM_MYMSGが来たらnCountにlpをコピーします。 ダイアログ側からの送信です。これを受け取った後クライアント領域を 更新して最新情報を表示させます。

WM_PAINTメッセージが来たらクリック数表示を行います。

メニューのIDM_PROGが選択されたらダイアログボックスを表示します。

LRESULT CALLBACK MyDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) { static HWND hProg1, hProg2, hStatic1, hStatic2, hParent; static int nClick; char szNum[8]; switch (msg) { case WM_INITDIALOG: nClick = 0; hProg1 = GetDlgItem(hDlg, IDC_PROGRESS1); hProg2 = GetDlgItem(hDlg, IDC_PROGRESS2); hStatic1 = GetDlgItem(hDlg, IDC_STATIC1); hStatic2 = GetDlgItem(hDlg, IDC_STATIC2); hParent = GetParent(hDlg); SendMessage(hProg1, PBM_SETRANGE, 0, MAKELPARAM(0, BAR_MAX)); SendMessage(hProg2, PBM_SETRANGE, 0, MAKELPARAM(0, BAR_MAX)); SendMessage(hProg1, PBM_SETSTEP, 1, 0); SendMessage(hProg2, PBM_SETSTEP, 1, 0); SendMessage(hProg1, PBM_SETBKCOLOR, 0, (LPARAM)RGB(255, 255, 0)); SendMessage(hProg1, PBM_SETBARCOLOR, 0, (LPARAM)RGB(255, 0, 0)); SendMessage(hProg2, PBM_SETBKCOLOR, 0, (LPARAM)RGB(255, 0, 255)); SendMessage(hProg2, PBM_SETBARCOLOR, 0, (LPARAM)RGB(0, 255, 0)); SendMessage(hProg1, PBM_SETPOS, 0, 0); SendMessage(hProg2, PBM_SETPOS, 0, 0); SetWindowText(hStatic1, "0"); SetWindowText(hStatic2, "0"); SendMessage(hParent, WM_MYMSG, 0, 0); return TRUE; case WM_COMMAND: switch (LOWORD(wp)) { case IDOK: nClick++; if (nClick <= BAR_MAX) { SendMessage(hProg1, PBM_STEPIT, 0, 0); SendMessage(hProg2, PBM_STEPIT, 0, 0); wsprintf(szNum, "%d", nClick); SetWindowText(hStatic1, szNum); SetWindowText(hStatic2, szNum); SendMessage(hParent, WM_MYMSG, 0, (LPARAM)nClick); } else nClick = BAR_MAX; return TRUE; case IDC_CLEAR: SendMessage(hProg1, PBM_SETPOS, 0, 0); SendMessage(hProg2, PBM_SETPOS, 0, 0); nClick = 0; SetWindowText(hStatic1, "0"); SetWindowText(hStatic2, "0"); SendMessage(hParent, WM_MYMSG, 0, (LPARAM)nClick); return TRUE; case IDCANCEL: EndDialog(hDlg, IDCANCEL); return TRUE; } return FALSE; } return FALSE; }

WM_INITDIALOGメッセージが来たら諸準備を行います。
nClickを0にします。
プログレスバーコントロールのハンドルを取得しておきます。
プログレスバーの範囲をPBM_SETRANGEで設定します。
プログレスバーのステップ値をPBM_SETSTEPで設定します。
PBM_SETBKCOLOR, PBM_SETBARCOLORでプログレスバーの背景と バーの色を設定します。

PBM_SETBKCOLOR wParam = 0; lParam = (LPARAM)(COLORREF)clrBk;

clrBkに背景色を設定します。
戻り値は以前の背景色です。 以前の背景色がデフォルトである場合はCLR_DEFAULTが返されます。

PBM_SETBARCOLOR wParam = 0; lParam = (LPARAM)(COLORREF)clrBar;

clrBarにバーの色を設定します。
戻り値は以前のバーの色です。以前のバーの色がデフォルトで合った場合は CLR_DEFAULTが返されます。

次にバーの位置をPBM_SETPOSで0にしておきます。
また、スタティックコントロールに0を表示させます。
最後に親ウィンドウにWM_MYMSGを送ってクリック数を知らせます。

「CLICK!」(IDOK)ボタンが押された時クリック数が最大値を越えていない時は PBM_STEPITで1ステップ増加させます。そしてクリック数をWM_MYMSGで 親に知らせます。

「CLEAR」(IDC_CLEAR)ボタンが押された時はバーの位置を0にします。 そして、WM_MSGでクリック数を親に知らせます。

と、まあこんなところです。 特に難しくはないと思います。


[SDK第2部 Index] [総合Index] [Previous Chapter] [Next Chapter]

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