C++Builder Tips - C++Builder でイメージビューアを作る

Abstract: 簡単なアプリケーションを作成する手順に従って、一般的なC++Builderによるアプリケーション開発ステップの例を紹介します。

このドキュメントでは,イメージビューアを作成します。イメージビューアは、ビットマップデータを表示するプログラムです。ビットマップは等倍(100%)、拡大(200%)、縮小(50%)の表示が可能です。ビットマップファイルを開くには、ダイアログボックスを用います。

    1. フォームの設計

C++Builderのアプリケーション開発は、フォームの設計から開始します。フォーム上にコンポーネントを配置し、それらのプロパティを設定し、イベントハンドラを記述するのがC++Builderの開発ステップになります。

はじめに、フォーム上にScrollBoxを配置します。ScrollBoxは、コンポーネントパレットの[Additional]ページにあります。次に配置したScrollBoxの上に、同じページにあるImageコンポーネントを配置します。そして、[Win95]ページにあるStatusBarをフォーム上の他の場所(ScrollBoxの上以外)に配置します。

配置したそれぞれのコンポーネントのプロパティを、オブジェクトインスペクタを使って次のように設定します。

ScrollBox1

プロパティ

設定値

Align

alClient

Image1

プロパティ

設定値

Left

0

Top

0

Strech

true

StatusBar1

プロパティ

設定値

SimplePanel

true

Alignプロパティは、コンポーネントのレイアウトを制御します。StatusBarはあらかじめAlignプロパティがalBottomに設定されていますから、フォームの下部に配置されます。ScrollBoxのAlignプロパティをalClientに設定すると、ScrollBoxはフォームの残りの領域全体に表示されます。

Hide image
fig_1

    2. メニューの設計

メインメニューは、MainMenuコンポーネントを用いて作成します。[Standard]ページからMainMenuコンポーネントをフォームに配置します。MainMenuのようなコンポーネントは、コンポーネント自身が実行時には表示されない非表示コンポーネントです。非表示コンポーネントは、フォーム上のどこに配置してもかまいません。

Hide image
fig_2

配置したMainMenuコンポーネントをダブルクリックすると、メニューデザイナが表示されます。メニューデザイナは、メニュー項目を設計するためのツールです。メニュー項目は、メニューデザイナに表示されたプレースフォルダを用いて作成していきます。メニュー項目の設定を行なうのはオブジェクトインスペクタです。メニューデザイナで[Enter]キーを押すと、オブジェクトインスペクタに新しく作成するメニュー項目のプロパティが表示されます。

メニュー項目の表示文字列は、Captionプロパティで設定します。このアプリケーションで作成するメインメニューは、次のような階層になっています。

&File

&View

&Open...

&50%

&Close

&100%

-

&200%

E&xit

&に続く文字は、アクセラレータキーを表わします。&Fのように記述していると、Fに下線が表示され、Fがアクセラレータキーとして機能します。また、Captionにハイフン(-)を設定すると、区切り線を表わすことができます。Viewメニューの3つの項目は、ラジオ項目として機能させます。これらのメニュー項目のRadioItemプロパティをtrueに設定し、GroupIndexを1に設定します。メニューの設計が終わったら、メニューデザイナを閉じます。

    3. コモンダイアログの使用

ビットマップファイルを指定するダイアログボックスは、[Dialogs]ページのOpenDialogコンポーネントを利用します。OpenDialogコンポーネントは、コモンダイアログをカプセル化したコンポーネントです。OpenDialogコンポーネントをフォーム上に配置し、オブジェクトインスペクタでFilterプロパティの値の横に表示されている[...]ボタンを押します。表示された「フィルタの設定」ダイアログで次の項目を入力します。

  • フィルタ名:ビットマップ(*.bmp)
  • フィルタ :*.bmp

設計フォームのOpenメニューを選択すると、コードエディタにイベントハンドラが表示されます。ここに次のようなOpenDialogを使用するコードを記述します(太字部分)。

   void __fastcall TForm1::Open1Click(TObject *Sender)
   {
       if (OpenDialog1->Execute()){
           Image1->Picture->LoadFromFile(
               OpenDialog1->FileName);
           Caption = ExtractFileName(
               OpenDialog1->FileName);
       }
   }

ついでに、CloseメニューとExitメニューも作成します。それぞれのメニューを選択して、以下のコードを記述して下さい。

   // Closeメニュー
   void __fastcall TForm1::Close1Click(TObject *Sender)
   {
       Image1->Picture = NULL;
       Caption = "";
   }
   
   // Exitメニュー
   void __fastcall TForm1::Exit1Click(TObject *Sender)
   {
       if (Application->MessageBox(
          "プログラムを終了します.よろしいですか?",
          "確認",
           MB_ICONQUESTION | MB_YESNO) == ID_YES)
         Close();
   }

    4. メソッドの追加

ImageコンポーネントのStretchプロパティをtrueにしていると、ビットマップをImageコンポーネントの大きさに伸縮表示します。これを利用してビットマップの拡大、縮小を行ないます。Imageコンポーネントの大きさを、ビットマップの大きさによって変更するようなメソッドを作成し、これを利用して拡大、縮小機能を実装します。

このメソッドは、フォームのメンバ関数として作成してみましょう。フォームは、デフォルトでTForm1という名前のクラスです。このクラスの宣言は、ユニットのヘッダファイルにあります。コードエディタでマウスの右ボタンを押して表示されるメニュー(コンテキストメニュー)で、[ソース/ヘッダ ファイルを開く]メニューを選択すると、ヘッダファイルが表示されます。

ここで、TForm1のクラス宣言のprivateメンバとしてメソッドを宣言します。

   private:        // ユーザー宣言
       void __fastcall SetImageScale(int AScale);

続いて、メソッドの定義をソースファイル(デフォルトではUnit1.cpp)に記述します。

   void __fastcall TForm1::SetImageScale(int AScale)
   {
       Image1->Width 
         =(Image1->Picture->Width  * AScale) / 100;
       Image1->Height
         =(Image1->Picture->Height * AScale) / 100;
       // 設定したスケールをステータスバーに表示
       StatusBar1->SimpleText 
          = IntToStr(AScale) + "%";
   }

OpenメニューのOnClickイベントも次のように変わります。

   void __fastcall TForm1::Open1Click(TObject *Sender)
   {
       if (OpenDialog1->Execute()){
           Image1->Picture->LoadFromFile(
               OpenDialog1->FileName);
           Caption = ExtractFileName(
               OpenDialog1->FileName);
           SetImageScale(100);
           N1001->Checked = true;
       }
   }

N1001は、Viewメニューの100%を表わします(これらの名前は、メニュー項目を作成したときにIDEが自動的に作成した名前です。分かりやすい名前にするために、コンポーネントのNameプロパティを変更することもできます)。この項目を選択されたことにするため、Checkedプロパティをtrueに設定しています。

    5. イベントハンドラの共用

イベントハンドラは、同じ型の関数であれば複数のコンポーネントのイベントで共用することができます。Viewメニューの各項目は、SetImageScaleを呼び出すだけですから、同じ処理が可能です。これらのイベントハンドラを共用して、コーディングを簡略化してみましょう。まず、50%メニューを選択して、自動的に生成されたN501Clickというイベントハンドラの名前を変更します。名前の変更は、オブジェクトインスペクタで行ないます。オブジェクトインスペクタのイベントページのOnClickに表示された関数名を変更すると、コードエディタの自動生成された関数の名前も変更されます。ここでは、ViewClickという名前にします。

この関数では、SetImageScaleを呼び出しますが、それぞれのメニューによって引数に指定する値が異なります。コンポーネントに特定の値を結び付けたいときは、Tagプロパティを用いることができます。Tagプロパティは、全てのコンポーネントに用意された、特に使用されることのない整数プロパティです。Tagプロパティに50を設定すれば、この値を用いてSetImageScale関数をコールできます。

選択されたメニュー項目を特定するのは、イベントハンドラ関数のSender引数です。Senderは、TObject型へのポインタですが、イベントを発生させたコンポーネントへのポインタが入っています。TMenuItemへのポインタにキャストすることで、選択されたTMenuItemコンポーネントにアクセスできます。

ViewClick関数は、次のようになります。

   void __fastcall TForm1::ViewClick(TObject *Sender)
   {
       SetImageScale(((TMenuItem *)Sender)->Tag);
       ((TMenuItem *)Sender)->Checked = true;
   }

もちろん、50%メニュー(N501)のTagプロパティは、50に設定されていなければなりません。100%、200%メニューも同じようにTagプロパティを100、200に設定し、ViewClick関数をイベントハンドラに設定します。これらの項目は、オブジェクトインスペクタのオブジェクトセレクタの右にあるドロップダウンボタンを用いて、N1001、N2001を選択することで設定できます。イベントハンドラの選択は、同じようにOnClickイベントの横に表示されるドロップダウンボタンを押して、表示された関数からViewClickを選択して行ないます。

    6. アプリケーションの完成

以上でイメージビューアの基本的な機能は完成しました。[実行]メニューか、[F9]を押してプログラムをテストしてみて下さい。このアプリケーションにはいくつか改良しなければならない点があるでしょう。

しかしC++Builderでは、テスト可能なアプリケーションが簡単に作成でき、インクリメンタルリンカによって修正後のアプリケーションの構築が高速に行なえます。 C++Builderでは、アプリケーションをテストすることで、問題点を明らかにし、修正を施すというステップが迅速に行なえるのです。

Hide image
fig_3

-->