ぴぐノート

Good code is its own best documentation.

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

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

投稿日:

プログレスバーをマルチスレッドを用いた実装について最後の記事です。
引き続き作成の目的は、

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

でした。
今回はプログレスバーが表示されるダイアログ(DIALOG2)の実装を確認します。
こちらはスレッド呼び出しなどはないため、簡単な内容になっています。

関連リンク:【MFC】マルチスレッドでプログレスバーを実装しよう その1
関連リンク:【MFC】マルチスレッドでプログレスバーを実装しよう その2

PrgDlg.cpp

最初の記事でOnInitDialog関数、WindowProc関数をそれぞれオーバーロードしました。
OnInitDialog関数で進行状況バーの下限/上限を設定します。
次にWindowProc関数でプログレスバーの現在位置を設定します。

WindowProc関数はダイアログにメッセージが発行されると呼ばれるため、頻繁に呼ばれる関数です。
実際に運用する場合は定期的に呼ばれるような関数を定義するといいかもしれません。

OnInitDialog関数

コントロール変数m_PrgCtrl(CProgressCtrl型)のSetRange関数でプログレスバーの下限/上限を設定します。
今回はマジックナンバーで【10,000,000】と記載していますが、定数を利用したり、ファイル走査などであれば総ファイル数を指定するなどが考えられます。

関連リンク:CProgressCtrl クラス | MSDN
関連リンク:CProgressCtrl::SetRange | MSDN

WindowProc関数

WindowProc関数ではウィンドウハンドルが作成されていれば、OnInitDialog関数で設定した上限と別スレッドでインクリメントされ続けているカウンター変数を比較し、まだ上限に達していなければ進行状況バーを更新します。

既に上限に達している場合はWM_CLOSEをポストし、ダイアログを閉じるように指示しています。

ウィンドウハンドルが作成されているかどうかの確認をしない場合は、実行時エラーが表示されます。これはWindowProc関数内で比較などをしているためです。

関連リンク:WindowProc 関数 | MSDN
関連リンク:CProgressCtrl::SetPos | MSDN

さて、これでようやく完成です。
実行してみると確かに少しずつプログレスバーがカウンタの値によって増加されているのが分かるかと思います。

multithread-progress_005
multithread-progress_006

問題点

さて、これまでの流れでプログレスバーをマルチスレッドで実装することはできました。
ですが、各所で見られたように問題点も多いです。

  • スレッドで実行する処理が、プログレスバーを表示するダイアログ作成前に完了する。
    → 例えば、void ThreadProc(void)を何も処理しないようにするとダイアログ生成よりも早くスレッドが閉じられ意図しない動作になるでしょう。

他にもマジックナンバーを埋め込んでいたり、色々問題点がありました。
こういった点をスマートに解決するためにはやはりVisual C++などの書籍を購入し、セマフォなども含めて学習の必要がありそうです。

まとめ

短いプログラムでしたがスレッドの生成について確認してみました。
今回紹介した方法は【ワーカースレッド】を用いた方法で実装しました。

実際に運用する場合には専用の関数を用意するなど、より堅牢なプログラムを行う必要がありそうです。

スポンサーリンク

スポンサーリンク

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

執筆者:

関連記事

【MFC入門】エディットコントロールの使い方【Visual C++】

前回はボタンが押された際のイベントハンドラーを実装しました。 今回はボタンと同じく利用機会の多いEdit Controlについて実装してみましょう。 ダイアログエディターからEdit Controlを …

【Boost】boost::property_treeの例外処理を考えよう!

ライブラリなどを使用していると、「使い方は大体分かった!使ってみよう!」とすると微妙にはまってしまうことがあります。 前回・前々回でお話しした文字コードもその一つですが今回は例外処理について考えてみま …

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

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

【MFC】フォルダー選択ダイアログの表示【Visual C++】

出力先の指定などフォルダー選択のダイアログを表示させたいことがあります。 フォルダー選択ダイアログを表示させるためには、SHBrowseForFolder関数を使います。 SHBrowseForFol …

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

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