C++BuilderでTProgressBarがうまく動かない
アプリケーションの起動に時間を要する場合は、スプラッシュスクリーンを準備します。ちなみに、スプラッシュスクリーンというのは、例えばMicrosoft officeのWord 2013であれば、こういうやつです。
設ける目的は、アプリケーションが起動していることをユーザーに通知することです。起動時、しばらく何も出てこなかったら、「本当に起動しようとしているの?」とユーザーが不安になってしまいますから。
そのついでにシステム名称や社名をコマーシャルしたり、アプリケーションのバージョンを表示したりするわけですが、スクリーン内にプログレスバーを設けて、起動の進捗状況を報告することがあります。
で、今回C++Builderで開発するアプリケーションに、VCLのTProgressBarを使って実装しようと思ったのですが、TProgressBarをWindows 7(XPの頃からかもしれないけど)で動かそうとすると、どうも更新したステップ数と、表示されているステップ数が合いません。
いろいろ考えたのですが、結局解決することができず、以下のような小細工をしました。小細工の内容は、setProgressMax()の長ったらしいコメントを参照してください。
TForm_Splash.cpp
/*! プログレスバーの最大値設定 @param max :全ステップ数(progressUpdate()をコールする回数) @return なし。 */ void __fastcall TForm_Splash::setProgressMax(int max) { /* TProgressBarに対してStepIt()すると、遅延して描画されるためか 1ステップ遅れたり、一気に2ステップ進んだり等して、綺麗に進捗を表示できない。 ずれは1ステップ程度のため、誤魔化し処理として指定された最大値に 16を乗算し、1ステップでpositionプロパティを16進めるようにすることで、 見た目上のずれを軽減している。 また、本クラスを利用するクラスの方で、最後にApplication->ProcessMessages()をコールして Windowsのメッセージキューを処理させないと、最終ステップが描画されない。 何故か、progressUpdate()でやってもダメで、利用元クラスでやる必要がある。訳が分からない。 そして、100%になった時に微量に100%にならないのは、どうにもならなかった。ギブアップ。 こんな小細工ばかりを組み込みたくなければ、TCGuageコンポーネントで代用できる。 しかし、ランタイムの関係かビジュアルが美しくない(Windows7っぽくない)ので今回はパスする。 */ ProgressBar->Max = (max * 16); // 最大値を16倍にしておいて ProgressBar->Step = 16; // 1ステップ[ 一度のStepIt() ]でPositionが16進むようにする。 ProgressBar->Position = 0; } /*! ユーザー向けに表示しているメッセージを更新し、プログレスバーを1段階進める。 @param userMessage :フォームに表示するユーザー向けメッセージ @return なし。 */ void __fastcall TForm_Splash::progressUpdate(const UnicodeString &userMessage) { if (!userMessage.IsEmpty()) { Label_UserMessage->Caption = userMessage; } ProgressBar->StepIt(); Application->ProcessMessages(); }
TForm_Main(利用元クラス)
// スプラッシュフォームクラスに、初期化の全ステップ数を通知 Form_Splash->setProgressMax(10); Form_Splash->progressUpdate(L"データベースへ接続中"); connectDatabase(); ・ ・ ・ Form_Splash->progressUpdate(L"システム設定データのロード中..."); systemDataLoad(); Form_Splash->progressUpdate(L"初期化完了!!"); Application->ProcessMessages(); // 大事なおまじない。理由はTForm_Splash.cppを参照
最近、コードに言い訳のコメントを残すことが多くなっている気がします。まあ、後から見た人が謎コードの目的を理解できるので、書かないよりは良いのですが、言い訳しなくても良いコードを実装するのが当然ベストなわけで、なんだかなー、と思う毎日でございます。
ではでは。