ぴぐノート

Good code is its own best documentation.

C/C++ MFC プログラミング言語

【MFC】マルチスレッドでプログレスバーを実装しよう その1

投稿日:2016年11月28日 更新日:

実は今回紹介する方法は、もしかしたら正しくないのかもしれません。
ダイアログベースのプログラムで以下の条件を満たし、プログレスバーを表示したいと考えました。

  • スレッド実行中はモーダルダイアログを表示させること。
  • モーダルダイアログではプログレスバーを表示し進捗が分かること。
  • 実行中のスレッドはダイアログのメンバーにアクセスできること。
  • スレッド処理が完了次第、モーダルダイアログを閉じること。

まだマルチスレッドに対して理解がないので、鵜吞みにせずこういった実装もできるという雑記程度に見ていただければと思います。

プロジェクト作成

まずはいつも通りにプロジェクトを作成しましょう。

関連リンク:無料のVisual StudioをインストールしてMFCを動かそう

外観(リソースビュー)

プロジェクトを作成したら、リソースエディターにて以下のようなダイアログを作成します。
これをDIALOG1としましょう。

multithread-progress_001

次に、スレッドを実行中に表示するモーダルダイアログを作成します。
これをDIALOG2とします。

  • ソリューションエクスプローラーを右クリック
  • [追加] – [リソース] – [Dialog]を選択し、[新規作成]クリック
    multithread-progress_002
  • 新しいダイアログがリソースエディターに表示されます。
    [Progress Control]を追加し以下のようなダイアログを作成します。
    multithread-progress_003

これで外観は完成としましょう。

クラス・変数の追加

DIALOG1

まず、先に作ったダイアログ(DIALOG1)にボタンを押下された際のイベントハンドラーを追加します。

  • リソースエディターで追加したボタンを右クリック
  • [イベントハンドラーの追加]クリック
  • [メッセージの種類]が「BN_CLICKED」となっていることを確認し、[追加して編集]をクリック。
DIALOG2

次にプログレスバーを追加したモーダルダイアログ(DIALOG2)にもクラス、変数を追加します。

  • ダイアログ全体を選択し右クリック
  • [クラスの追加]クリック
  • MFC クラス追加ウィザードに以下の内容で入力します。
    クラス名:CPrgDlg
    基底クラス:CDialog
  • [完了]ボタンをクリックします。

ここでPrgDlg.hの編集、ソースエディターになりますが再度リソースエディターに戻り、変数と仮想関数の追加を行います。

  • [Progress Control]が選択された状態で右クリック
  • [変数の追加]クリック
  • メンバー変数の追加ウィザードに以下の内容で入力します。
    アクセス:private
    変数名:m_PrgCtrl
    他はデフォルトのままです。(変数の種類:CProgressCtrlなど)
  • [完了]ボタンをクリックします。

次に、基底クラスの仮想関数をオーバーライドします。

  • ダイアログ全体を選択し右クリック
  • [クラスウィザード]クリック
  • 仮想関数タブに合わせ、以下の2つをダブルクリックします。
    OnInitDialog
    WindowProc
    multithread-progress_004
  • [OK]ボタンをクリックし、クラスウィザードを閉じます。

ここまでで、リソースエディターからの編集は完了です。
次に実行される制御関数と実際にメンバー変数などを扱う実行メンバー関数を定義します。

ヘッダーファイルの編集

{プロジェクト名}Dlg.h

さて、まずはヘッダーファイルに制御関数と実行メンバー関数、そしてDIALOG2から監視されるカウンタを宣言します。

プログレスバーを表示するDIALOG2から、制御用のカウンターにアクセスしたいのでフレンドクラスとしてCPrgDlgを追加しました。

そして、スレッドが実行された際に呼ばれる関数、

を定義します。
static が付いているため、メンバー変数にはアクセスできません。
そのため、メンバー変数にアクセスする関数、

も宣言します。
このThreadProc()は、ThreadProc(LPVOID)の中から呼ばれることになります。

さて、長くなってしまうのでソースコードは明日編集することにしましょう。

まとめ

冒頭で「正しくないかもしれません。」と述べたように実際にはVisual C++の書籍などを購入し、セマフォなども踏まえてしっかり学習をするべきです。

私の実装でも概ね目的は達成できていますが、堅牢なプログラムというにはほど遠い状態です。
暫定の実装くらいに考えておいてください。

スポンサーリンク

スポンサーリンク

-C/C++, MFC, プログラミング言語

執筆者:

関連記事

【Boost】boost::property_treeでXMLファイルを書き込もう!

前回の記事でXMLファイルの書き込みは難しくなくできそうでしたネ。 今回はXMLファイルの書き込みを行い、出力してみましょう。 読み込みと同じくライブラリファイルは不要で、ヘッダーファイルのみで利用で …

【MFC入門】ダイアログにファイルをドラッグアンドドロップしよう【Visual C++】

ファイル操作を行うツールなどを作成する際には、ファイルをドラッグアンドドロップできると便利です。 ファイルがどこにあるか分からない場合などは参照させることも多いと思いますが、プログラムやファイルの検証 …

C++でインターフェイスを作成しよう。

私事ですが今後業務ではC++を使用することになりそうです。 今まではウェブ関連の業務であったり、ちょっとしたテスト程度だったのでJavaを中心に使っていたため、C++の文法など少し忘れ気味です&#82 …

【MFC入門】メッセージボックスにエラーコードを表示させよう

ライブラリなどを使用していると、戻り値にエラーコードを返す関数は比較的多いです。 GetLastError関数(最新のエラーコードを取得する関数)がライブラリに含まれていることもありますが、そうでない …

C++のプリプロセッサの復習をしよう その1

C++を勉強していた時期から苦手だったのがプリプロセッサでした。 インクルートガードに#ifndefやら#defineやら#pragma onceやら…。 C++に限った話ではありませんが …