実は今回紹介する方法は、もしかしたら正しくないのかもしれません。
ダイアログベースのプログラムで以下の条件を満たし、プログレスバーを表示したいと考えました。
- スレッド実行中はモーダルダイアログを表示させること。
- モーダルダイアログではプログレスバーを表示し進捗が分かること。
- 実行中のスレッドはダイアログのメンバーにアクセスできること。
- スレッド処理が完了次第、モーダルダイアログを閉じること。
まだマルチスレッドに対して理解がないので、鵜吞みにせずこういった実装もできるという雑記程度に見ていただければと思います。
Contents
プロジェクト作成
まずはいつも通りにプロジェクトを作成しましょう。
関連リンク:無料のVisual StudioをインストールしてMFCを動かそう
外観(リソースビュー)
プロジェクトを作成したら、リソースエディターにて以下のようなダイアログを作成します。
これをDIALOG1としましょう。
次に、スレッドを実行中に表示するモーダルダイアログを作成します。
これをDIALOG2とします。
- ソリューションエクスプローラーを右クリック
- [追加] – [リソース] – [Dialog]を選択し、[新規作成]クリック
- 新しいダイアログがリソースエディターに表示されます。
[Progress Control]を追加し以下のようなダイアログを作成します。
これで外観は完成としましょう。
クラス・変数の追加
DIALOG1
まず、先に作ったダイアログ(DIALOG1)にボタンを押下された際のイベントハンドラーを追加します。
- リソースエディターで追加したボタンを右クリック
- [イベントハンドラーの追加]クリック
- [メッセージの種類]が「BN_CLICKED」となっていることを確認し、[追加して編集]をクリック。
DIALOG2
次にプログレスバーを追加したモーダルダイアログ(DIALOG2)にもクラス、変数を追加します。
- ダイアログ全体を選択し右クリック
- [クラスの追加]クリック
- MFC クラス追加ウィザードに以下の内容で入力します。
クラス名:CPrgDlg
基底クラス:CDialog - [完了]ボタンをクリックします。
ここでPrgDlg.hの編集、ソースエディターになりますが再度リソースエディターに戻り、変数と仮想関数の追加を行います。
- [Progress Control]が選択された状態で右クリック
- [変数の追加]クリック
- メンバー変数の追加ウィザードに以下の内容で入力します。
アクセス:private
変数名:m_PrgCtrl
他はデフォルトのままです。(変数の種類:CProgressCtrlなど) - [完了]ボタンをクリックします。
次に、基底クラスの仮想関数をオーバーライドします。
- ダイアログ全体を選択し右クリック
- [クラスウィザード]クリック
- 仮想関数タブに合わせ、以下の2つをダブルクリックします。
OnInitDialog
WindowProc
- [OK]ボタンをクリックし、クラスウィザードを閉じます。
ここまでで、リソースエディターからの編集は完了です。
次に実行される制御関数と実際にメンバー変数などを扱う実行メンバー関数を定義します。
ヘッダーファイルの編集
{プロジェクト名}Dlg.h
さて、まずはヘッダーファイルに制御関数と実行メンバー関数、そしてDIALOG2から監視されるカウンタを宣言します。
1 2 3 4 5 6 7 8 9 10 |
class CMy002_PrgDlgDlg : public CDialogEX { friend class CPrgDlg; public: static UINT ThreadProc(LPVOID pParam); void ThreadProc(); private: static int nCount; } |
プログレスバーを表示するDIALOG2から、制御用のカウンターにアクセスしたいのでフレンドクラスとしてCPrgDlgを追加しました。
そして、スレッドが実行された際に呼ばれる関数、
1 |
static UINT ThreadProc(LPVOID pParam); |
を定義します。
static が付いているため、メンバー変数にはアクセスできません。
そのため、メンバー変数にアクセスする関数、
1 |
void ThreadProc(); |
も宣言します。
このThreadProc()は、ThreadProc(LPVOID)の中から呼ばれることになります。
さて、長くなってしまうのでソースコードは明日編集することにしましょう。
まとめ
冒頭で「正しくないかもしれません。」と述べたように実際にはVisual C++の書籍などを購入し、セマフォなども踏まえてしっかり学習をするべきです。
私の実装でも概ね目的は達成できていますが、堅牢なプログラムというにはほど遠い状態です。
暫定の実装くらいに考えておいてください。