今回はC++ Builderでの始めてのプログラムとして「お絵描きソフト」を作ってみましょう。マウスで線を引く事ができ、線の色も下の方のパレットで選択できるというプログラムです。これもC++ Builderなら適当に部品を置いていくつかの「イベント」用に何行かコードを書くだけでできてしまいます。

実行画面

部品を配置

 まず、C++ Builderを起動してフォームが表示されたら、コンポーネントを配置できるようにフォームの大きさを変えておきます。大体横360、縦430程度にすれば良いでしょう。フォームの端を適当にドラッグするか、オブジェクトインスペクタでWidthHeightを変更してください。

 配置するコンポーネントは描画する画面用と色を選択するパレット用合わせて2つののImageコンポーネントだけです。描画画面の方は、画面の上の方にImegeコンポーネントを置いてください。大きさは、320四方ぐらいにしましょう。Width、Heightともに320に設定します。位置は大体左上端、端から4-8ドットくらいあけて置きましょう(Left、Topで設定します)。
 パレット用のImegeコンポーネントは描画画面のすぐ下に置きます。こちらは正確に大きさを決めたいので、オブジェクトインスペクタでWidthを258 にHeightを34 にしてください。ここで、もしImegeコンポーネントがフォーム内に入りきらないでスクロールバーが出てきたら、フォームを広げてフォーム内に収まるようにしましょう。

コードを書く

 フォームを配置できたらいよいよ「プログラミング」です。まず、Imegeコンポーネントにわかりやすいよう名前を付けておきます。名前は何でもよいのですが、ここでは描画画面の方はscreen、色選択の方はpalleteとでもしておきましょう。オブジェクトインスペクタのNameを変えるとそれがそのオブジェクト(ここではImegeコンポーネント)の名前になります。
 次に、色の選択をするためのパレットを作りましょう。オブジェクトインスペクタの上端にある「イベント」をクリックすると、プロパティからイベント表示になるので、そこの「OnCreate」をダブルクリックします。これは、プログラムが起動されてフォームが作られた時に実行されるイベントハンドラです。パレットは起動したらすぐに作っておく必要があるので、ここで作ります。ダブルクリックすると、コードエディタが出てきましたね。

=====
void __fastcall TForm1::FormCreate(TObject *Sender)
{


}
//---------------------------------------------------------------------------
=======

 このようになっているはずですが、フォームが作られた時の処理は、{ と } の間に書きます。今回の場合、必要なのは描画画面を初期化してパレットを作る処理です。まず、描画画面は白く塗りつぶして周りに黒い枠でも付けておけば良いでしょう。

  screen->Canvas->Brush->Color=clWhite; //描画画面を白く塗りつぶす
  screen->Canvas->FillRect(Rect(1,1,321,321));
  screen->Canvas->Brush->Color=clBlack; //黒い枠を付ける
  screen->Canvas->FrameRect(Rect(0,0,322,322));

 大きさが320四方ならこんな感じですね。次にパレットは白黒のグラテーションにします。色を決めるには、32ビット(4バイト)の整数値を指定するのですが、これはヘルプを見てもわかるように下位3バイトがそれぞれ青・緑・赤になっています。各色の成分は8ビット(1バイト)ですからそれぞれ0ー255の値を取り、大きいほどその色が強くなります。3つの色の成分は、上位から順に青、緑、赤の順に並んでいるので、色を指定するときの数値は以下のように計算できます。

 青×65536+緑×256+赤

 青に65536をかけているのは16ビットずらして3バイト(24ビット)のうち最上位8ビットに持ってくるため、緑に256をかけているのは8ビットずらして2バイト目にもってくるためです。最下位の赤はそのままですね。本当は、4バイトの最上位8ビットも意味があるのですが、とりあえず今回は0にしておきましょう。
 今回作るパレットは白黒なので、青・緑・赤をすべて同じ値にします。0-255まで256段階のパレットにしましょう。

======
  for (i=0;i<256;i++){ //選択用グラテーション作成

    pallete->Canvas->Brush->Color=i*65536+i*256+i;
    pallete->Canvas->FillRect(Rect(i+1,1,i+2,33));

  }
=====

 とすれば良いですね。選択する色は、最初は黒にしておきましょう。選択した色を表す変数clに0 (色で言えば青・緑・赤いずれもないので黒)を入れます。これで、OnCreateの処理は終わりです。
 ここで、ついでにこのプログラム全体で使う(グローバル)変数であるcldrawingも宣言しておきます。 コードエディタの上の方に何やら#の付いた文が書いてありますが、そのすぐ下で以下のように宣言してください。

  int cl;
  bool drawing;

 次に、描画画面でマウスのボタンを押すと点や線を描けるようにします。screen(描画画面用のImageコンポーネント) をクリックしてさらにオブジェクトインスペクタの「イベント」をクリックします。そこにある「On MouseDown」をダブルクリックしてください。これで、screenOn MouseDownイベントに対応する処理を書けるようになります。ここは以下のようにしてください。

======
void __fastcall TForm1::screenMouseDown(TObject *Sender, TMouseButton Button,
	TShiftState Shift, int X, int Y)
{

  screen->Canvas->Brush->Color=cl;//選択された色に設定
  screen->Canvas->FillRect(Rect(X,Y,X+4,Y+4));

  drawing=true; //描画開始

}
=======

 この部分は、まずマウスボタンが押されたらそこに大き目の点を打ち、さらに線を描けるようにdrawingtrueに設定しています。drawingはマウスボタンの状態に対応した変数で、マウスボタンが押されたら(つまりこの部分が呼び出されたら)trueに設定され、マウスボタンが離されるとfalseに設定されます。

 次に、マウスカーソルがscreen 上を移動すると発生する「On MouseMove」イベントの処理を書きましょう。「On MouseMove」の所をダブルクリックしてください。ここは、マウスボタンが押されているなら(drawingtrueなら)現在の座標に点を打つだけなので、以下のようになります。

=======
void __fastcall TForm1::screenMouseMove(TObject *Sender, TShiftState Shift,
	int X, int Y)
{

  if (drawing) { //マウスボタンが押されているなら

    screen->Canvas->Brush->Color=cl;
    screen->Canvas->FillRect(Rect(X,Y,X+4,Y+4));

  }

}
=======

 今度は、マウスボタンを離したら線を引くのを中止できるように「On MouseUp」イベントでdrawingfalseに設定します。「On MouseUp」をダブルクリック後、以下のコードを書きます。

======
void __fastcall TForm1::screenMouseUp(TObject *Sender, TMouseButton Button,
	TShiftState Shift, int X, int Y)
{

  drawing=false; //描画中止

}
=====

 最後に、パレットをクリックすると色を選択する処理を書きましょう。これも単純で、パレットがクリックされたらクリックされた所の色を選択された色を表す変数clに入れるだけです。パレットの色は、ビットマップのCanvasにあるPixelsプロパティを調べれば得られるので、以下のようになります。

=======
void __fastcall TForm1::palleteMouseDown(TObject *Sender, TMouseButton Button,
	TShiftState Shift, int X, int Y)
{

  cl=pallete->Picture->Bitmap->Canvas->Pixels[X][Y]; //色選択

}
=======

 さあ、これで完成です。「すべて保存」したら「実行」してみてください。どうでしょうか? うまく動きましたか? もし動かないようなら、ソースと見比べて見てください。ただし、ソースは部品を配置しないでそのまま写してもだめですよ。必ず、今まで書いてきたように部品を配置してオブジェクトインスペクタの「イベント」からコードを書くようににしてください。

プログラムソース表示
戻る