ぴぐノート

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, プログラミング言語

執筆者:

関連記事

C++のプリプロセッサの復習をしよう その2 【#defineの活用】

前回に引き続き、C++のプリプロセッサの復習です。 前回は#includeと#defineについて記事にしましたが、【まとめ】にも記載の通り、#defineと関連するプリプロセッサは多くあります。 今 …

【C++11】後処理が必要なリソースはスマートポインタを使おう

オープンソースのライブラリのソースコードを呼んでいるとC++11で追加されたunique_ptrを使用しているところもちらほらと見られるようになってきています。 MFCなどを利用していれば動的確保した …

Eclipse NeonとCDT/MinGWでC++開発環境を作成しよう!(1)

MFCなどを利用する場合にはほぼVisualStudio一択ですが、簡単なコンソールアプリケーションを作る場合にはEclipseのほうが便利な場合も多いです。 特に「普段はJavaで開発を行っているけ …

【Visual C++】フルパスを指定してフォルダー階層を作成する。

MFCなどでファイル走査などのプログラミングを行っていると、D&D(ドラッグアンドドロップ)されたフォルダー内の全ファイル(サブフォルダー含め)に何か処理を行い、同じような階層を維持したまま別 …

【Boost】オープンソースライブラリBoostをインストールしよう

普段からC++でのプログラムを作成していてBoost(ブースト)を知らないという人はあまり多くないかもしれませんが、「実はまだ使ったことない…」という人もいるのではないでしょうか? ライブ …