ぴぐノート

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】マルチスレッドでプログレスバーを実装しよう その1

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

【OpenCV】OpenCVをビルドして画像処理をしてみよう!

今日はOpenCVを使って画像表示をしてみたいと思います。 ツールやアプリケーションを作る場合、多かれ少なかれ画像処理は必要になってくるのではないでしょうか。 また画像処理関係ではまると泥沼化する場合 …

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

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

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

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

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

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