ナッキーの「Turbo Delphiはじめて奮戦記」 - 第7回 計算機に機能追加

By: Hitoshi Fujii

Abstract: 計算機に挑戦!ということで前回は画面を作成し、テンキーで数値が出るところまで作りました。たくさんコンポーネントを配置して大変だったなぁ。今回は前回作らなかった機能を追加していきます。

Hide image
nacky75

ナッキー

前回は画面作成が大変でしたよ。ボタンをたくさん作ったけど、今回はテンキー以外のボタンに機能をつけるんだったわね。どんな機能を付けるのかな?もっと難しくなるのかしら?

 

Hide image
takahashi75

高橋先生

今回はビシビシ進めるからね。画面の右半分のボタンに機能をつける。ここまでがんばったら一応計算機としての役に立つよ。記述が多いけどコピー&ペーストで作成できるから、がんばってみてね。

    演算ボタンの作成

前回のプロジェクトを開きます。Turbo Delphiを起動して画面中央の「ホームページ」で「Calclator.dbsproj」を選択。もし一覧に表示されていなければ、ツールバーの[プロジェクトを開く(Ctrl+F11)]ボタンをクリックします。「プロジェクトを開く」ダイアログボックスから「Calclator.bdsproj」を探します。

前回の練習で算数の式だと「A+B=?」の「A」は入力できました。次は演算のボタンね。ラベルに「+」と表示するだけでいいのかしら?

高橋先生: 演算ボタンを押したあとは、2番目の数値を入力する必要がある。だからedtInput1は黄色に、edtInput2は白に色を変更しよう。


じゃあ、はじめは、ラベルに演算記号を表示します。フォームデザイナでbtnTasuボタンを選択。次に、オブジェクトインスペクタの[イベント]ページで「入力」の「OnClick」をダブルクリックしてイベントハンドラを作成します。四則演算の記号をlblEnzanに入れればいいのよね。太字の部分を追加します。

procedure TfrmCalc.btnTasuClick(Sender: TObject);
begin
  lblEnzan.Caption := '';
end;

次にedtInput1とedtInput2の色を変更します。edtInput1が黄色、edtInput2が白だったわね。太字部分を書き加えます。

procedure TfrmCalc.btnTasuClick(Sender: TObject);
begin
  lblEnzan.Caption := '+';
  edtInput1.Color := clYellow;
  edtInput2.Color := clWhite;
end;

ここまでうまく動くかチェック!保存して実行してみましょう。ツールバーの[すべて保存]ボタンをクリックして上書き保存します。次に[実行]ボタンをクリックして起動します。数値を入力したあと「+」ボタンをクリック。

Hide image
01演算ボタン

図01 演算ボタン

ちゃんと動いた。では、調子よく「-」、「×」、「÷」のイベントハンドラも作成することにしましょう。表示をフォームデザイナに切り替えて「-」ボタンを選択。オブジェクトインスペクタの[イベント]ページで、「入力」の「OnClick」をダブルクリックしてイベントハンドラを作成します。先にイベントハンドラの枠だけ作っちゃいますね。フォームデザイナに戻って、同様の方法で「×」と「÷」ボタンの「OnClick」イベントハンドラの枠も作成します。次はコードエディタでbtnTasuのOnClickイベントハンドラの内容をコピーして、四則演算の記号部分を変更して作成っと。太字部分を追加します。

procedure TfrmCalc.btnHikuClick(Sender: TObject);
begin
  lblEnzan.Caption := '';
  edtInput1.Color := clYellow;
  edtInput2.Color := clWhite;
end;

procedure TfrmCalc.btnKakeruClick(Sender: TObject);
begin
  lblEnzan.Caption := '×';
  edtInput1.Color := clYellow;
  edtInput2.Color := clWhite;
end;

procedure TfrmCalc.btnWaruClick(Sender: TObject);
begin
  lblEnzan.Caption := '÷';
  edtInput1.Color := clYellow;
  edtInput2.Color := clWhite;
end;

できたら保存して、ここまでがうまく動くか実行テストしてみます。ツールバーの[すべて保存]ボタンで保存して、[実行]ボタンで実行。色を元に戻す方法がないので、1つずつ実行と終了を繰り返して確認します。

    2つ目の数値入力

2つ目のedtInput2に文字を入れなくっちゃ。今はテンキーを押すとedtInput1に入力されます。

高橋先生:四則演算の記号が入ったらedtInput2に入力することにしよう。条件はlblEnzanに記号が入っているかどうかで調べることにしよう。

lblEnzan.Caption = ''

「''」はシングルコーテーションを2つ並べたもの。「長さ0の文字列」と呼ばれている。文字が入っていないという状態。lblEnzanのCaptionプロパティに何も入っていなかったら「True」、入っていたら「False」になる。条件がTrueならedtInput1に文字を入力して、FalseならedtInput2に文字を入力するように書き換えてみよう。


コードエディタでsbtn1のOnClickイベントハンドラを探します。以前のコードは、「//」などでコメントにします。太字部分を追加します。

procedure TfrmCalc.sbtn1Click(Sender: TObject);
begin
//  edtInput1.Text := edtInput1.Text + '1'

  if lblEnzan.Caption = '' then
    edtInput1.Text := edtInput1.Text + '1'
  else
    edtInput2.Text := edtInput2.Text + '1';
end;

うまく動くか確認します。ツールバーの[すべて保存]ボタンで保存して、[実行]ボタンで実行してみましょう。1つ目の数値を何か入力したあと[+]ボタンをクリック。次に[1]ボタンをクリックすると、edtInput2に「1」が表示されるかな?

Hide image
02入力切替

図02 入力切り替え

うまくできたら、コードをほかのボタンのOnClickイベントハンドラにコピーします。

procedure TfrmCalc.btn0Click(Sender: TObject);
begin
//  edtInput1.Text := edtInput1.Text + '0';
  if lblEnzan.Caption = '' then
    edtInput1.Text := edtInput1.Text + '0'
  else
    edtInput2.Text := edtInput2.Text + '0';
end;

procedure TfrmCalc.btn2Click(Sender: TObject);
begin
//  edtInput1.Text := edtInput1.Text + '2';
  if lblEnzan.Caption = '' then
    edtInput1.Text := edtInput1.Text + '2'
  else
    edtInput2.Text := edtInput2.Text + '2';
end;

procedure TfrmCalc.btn3Click(Sender: TObject);
begin
//  edtInput1.Text := edtInput1.Text + '3';
  if lblEnzan.Caption = '' then
    edtInput1.Text := edtInput1.Text + '3'
  else
    edtInput2.Text := edtInput2.Text + '3';
end;

procedure TfrmCalc.btn4Click(Sender: TObject);
begin
//  edtInput1.Text := edtInput1.Text + '4';
  if lblEnzan.Caption = '' then
    edtInput1.Text := edtInput1.Text + '4'
  else
    edtInput2.Text := edtInput2.Text + '4';
end;

procedure TfrmCalc.btn5Click(Sender: TObject);
begin
//  edtInput1.Text := edtInput1.Text + '5';
  if lblEnzan.Caption = '' then
    edtInput1.Text := edtInput1.Text + '5'
  else
    edtInput2.Text := edtInput2.Text + '5';
end;

procedure TfrmCalc.btn6Click(Sender: TObject);
begin
//  edtInput1.Text := edtInput1.Text + '6';
  if lblEnzan.Caption = '' then
    edtInput1.Text := edtInput1.Text + '6'
  else
    edtInput2.Text := edtInput2.Text + '6';
end;

procedure TfrmCalc.btn7Click(Sender: TObject);
begin
//  edtInput1.Text := edtInput1.Text + '7';
  if lblEnzan.Caption = '' then
    edtInput1.Text := edtInput1.Text + '7'
  else
    edtInput2.Text := edtInput2.Text + '7';
end;

procedure TfrmCalc.btn8Click(Sender: TObject);
begin
//  edtInput1.Text := edtInput1.Text + '8';
  if lblEnzan.Caption = '' then
    edtInput1.Text := edtInput1.Text + '8'
  else
    edtInput2.Text := edtInput2.Text + '8';
end;

procedure TfrmCalc.btn9Click(Sender: TObject);
begin
//  edtInput1.Text := edtInput1.Text + '9';
  if lblEnzan.Caption = '' then
    edtInput1.Text := edtInput1.Text + '9'
  else
    edtInput2.Text := edtInput2.Text + '9';
end;

ちょっと長かったけど、コピペで楽しちゃった。これで、保存して実行。1つ目の値を適当に入力して、「+」ボタンなどをクリックしたあとedtInput2に数値が入力できるかを確認してみましょう。

Hide image
03入力切替完了

図03入力切り替え完了

    関数で型変換

2つの値が入れられたから、計算結果を出さなくっちゃ。edtInput1とedtInput2の値をlblEnzanに入れた方法で計算して、edtKekkaに出せばいいのね。イベントは[計算]ボタンをクリックしたとき。フォームデザイナでbtnKeisanボタンを選択して、イベントページで「OnClick」イベントハンドラを作成します。こんな感じでいいのかな?

procedure TfrmCalc.btnKeisanClick(Sender: TObject);
begin
  if lblEnzan.Caption = '+' then
    edtKekka.Text := dtInput1.Text + edtInput2.Text;
  if lblEnzan.Caption = '-' then
    edtKekka.Text := dtInput1.Text - edtInput2.Text;
  if lblEnzan.Caption = '×' then
    edtKekka.Text := dtInput1.Text * edtInput2.Text;
  if lblEnzan.Caption = '÷' then
    edtKekka.Text := dtInput1.Text / edtInput2.Text;
end;


if文の書き方は習ったからこれでバッチリのはず。保存して実行してみましょう。

あれ?コンパイルエラーになっちゃった。なになに「この型には指定した演算子は使えません」!なんで計算できないんだろう?教えて高橋先生!

高橋先生: Textプロパティの型のせいだね。文字列型としての「数字」だから、計算には使えないんだよ。「+」だけがエラーにならないのは、文字列の連結に使われるせいだな。もしこのまま「12」と「43」を足したら、edtKekkaには「1243」と表示されるよ。

どうやってedtInput1に入っている値を計算に用いるか。それはね、「型」を変えてしまえばいいんだよ。計算に使える型は、整数型か小数点が扱える実数型などだね。だから文字列型の値を、型変換関数を使って変換するんだよ。

ナッキー:「カタヘンカンカンスウ」?

高橋先生:以前、関数を使うと処理をして結果を返してくれるという話をした。型を変えたい値をパラメータとして渡すと、希望の型になった値を返してくれる。今回は文字列型を整数型にする。そんな時は「StrToInt」関数で変えられるよ。使い方は簡単。

変数 := StrToInt(変換したい文字列)

例えば

A := StrToInt('5963');

でAには「5963」という整数型の値が入る。

Integer型の変数を2つ用意してedtInput1とedtInput2の値を代入してみよう。


コードエディタで先ほど作成したbtnKeisanのOnClickイベントハンドラを表示します。beginの前に空白行を追加してvar節を追加します。変数名は「Num1」と「Num2」、型はInteger型にします。太字部分を追加しましょう。

procedure TfrmCalc.btnKeisanClick(Sender: TObject);
var
  Num1 : Integer;
  Num2 : Integer;
begin
…
end;


用意した変数それぞれにedtInput1 とedtInput2の値を、型変換関数を使って代入します。

procedure TfrmCalc.btnKeisanClick(Sender: TObject);
var
  Num1 : Integer;
  Num2 : Integer;
begin
  Num1 := StrToInt(edtInput1.Text);
  Num2 := StrToInt(edtInput2.Text);
 ...
end;


これで計算に使えるのね。じゃあNum1とNum2を足したものをedtKekkaに出そう。

高橋先生: ちょっと待って。型がそろっていないといけないのは、代入するときも同じ。だから、いきなり計算した数値をedtKekkaのTextプロパティで受けることはできないんだよ。変数を用意してまた型変換をやってね。その時用意する変数の型を、割り算の結果も受け入れられるようDouble型にしておこう。Integer型は小数点のない整数だけ格納できるけれど、Double型は小数点がついた値も格納できる。実数型と呼ばれるものの一種だよ。最後に格納した計算結果を文字列型に戻してedtKekkaに表示するけれど、その時使う関数は「FloatToStr」関数。

もう一つオマケで教えると、型変換関数に「StrToIntDef」というのがある。変換できなかった場合の代替値を用意できるんだ。文字列に何も入っていない時など、ちゃんと変換できないことがあるから、StrToInt関数よりStrToIntDef関数のほうが安全だよ。StrToIntDef関数にはパラメータが2つ。1つ目は変換したい文字列で、2つ目は変換できなかったときの代替値だ。

StrToInt('1')

文字列型から整数型

'1'→1

StrToFloat('1.5')

文字列型から実数型

'1.5'→1.5

IntToStr(2)

整数型から文字列型

2→'2'

FloatToStr(2.5)

実数型から文字列型

2.5→'2.5'

StrToIntDef('3',0)

文字列型から整数型

'3'→3

StrToIntDef('a',0)

変換できないときは代替値

'a'→0

ナッキー:型変換関数を使えば、入力した値で計算ができるんですね。


さてと、計算結果用の変数も用意してbtnKeisanのOnClickイベントハンドラを書き換えてみます。えっと、変数名は「Ans」、型名は「Double」型にしてっと…

procedure TfrmCalc.btnKeisanClick(Sender: TObject);
var
  Num1 : Integer;
  Num2 : Integer;
  Ans : Double;
begin
  Num1 := StrToIntDef(edtInput1.Text, 0);
  Num2 := StrToIntDef(edtInput2.Text, 0);
  if lblEnzan.Caption = '' then
    Ans := Num1 + Num2;
  if lblEnzan.Caption = '' then
    Ans := Num1 - Num2;
  if lblEnzan.Caption = '×' then
    Ans := Num1 * Num2;
  if lblEnzan.Caption = '÷' then
    Ans := Num1 / Num2;
  edtKekka.Text := FloatToStr(Ans);
end;

これでいいのかな?

高橋先生: if文がたくさん並んでいるね。このままだと、どんな演算のときもすべてのif文で条件をチェックしてしまうよ。lblEnzan.Captionが’+’ だったときは、次のif文で条件をチェックするのは無駄だよね。

こんなときは、case文にしたいんだけど、条件が文字列なのでcase文にはできない。そういう場合は、「else if文」を使って1文にまとめるんだ。

if A = 0 then
  //Aが0のときの処理
else if A = 1 then
  //Aが0ではなくて、Aが1のときの処理
else if A = 2 then
  //Aが0でも1でもなくて、Aが2のときの処理
else
  //すべての条件を満たさなかったときの処理;(最後だけ「;」を入力)

ナッキー:if文の中にif文を書くことができたけれど、else if文はその応用ですね。


if文をelse if文に換えて、if… else if… else if … else の1つの文にまとめておくのね。太字の部分を追加します。if文の中でセミコロンの部分は、最後以外を削除してしまいます。

procedure TfrmCalc.btnKeisanClick(Sender: TObject);
var
  Num1 : Integer;
  Num2 : Integer;
  Ans : Double;
begin
  Num1 := StrToIntDef(edtInput1.Text, 0);
  Num2 := StrToIntDef(edtInput2.Text, 0);
  if lblEnzan.Caption = '+' then
    Ans := Num1 + Num2 // セミコロン削除
  else if lblEnzan.Caption = '-' then
    Ans := Num1 - Num2 // セミコロン削除
  else if lblEnzan.Caption = '×' then
    Ans := Num1 * Num2 // セミコロン削除
  else if lblEnzan.Caption = '÷' then
    Ans := Num1 / Num2;
  edtKekka.Text := FloatToStr(Ans);
end;


高橋先生: もうちょっと付け加えて欲しい。if文の条件にどれも当てはまらなかったときのことを考えよう。たとえば起動してすぐに[計算]ボタンをクリックした場合などだ。Num1の値を代入することにすれば、何も入力されていなくても「0」が代入されるよ。


if文の最後にelse文を追加して変数AnsにNum1の値を代入します。

procedure TfrmCalc.btnKeisanClick(Sender: TObject);
var
  Num1 : Integer;
  Num2 : Integer;
  Ans : Double;
begin
  Num1 := StrToIntDef(edtInput1.Text, 0);
  Num2 := StrToIntDef(edtInput2.Text, 0);
  if lblEnzan.Caption = '+' then
    Ans := Num1 + Num2
  else if lblEnzan.Caption = '-' then
    Ans := Num1 - Num2
  else if lblEnzan.Caption = '×' then
    Ans := Num1 * Num2
  else if lblEnzan.Caption = '÷' then
    Ans := Num1 / Num2 //セミコロン削除
  else
    Ans := Num1;
  edtKekka.Text := FloatToStr(Ans);
end;


高橋先生:見た目も変更しよう。入力中のエディットは白にすることにしていたから、edtInput1とedtInput2の色を黄色に、edtKekkaの色を白に変更するよ。


エディットの色を変更します。edtInput1とedtInput2の「Color」プロパティに「clYellow」を代入。edtKekkaの「Color」プロパティに「clWhite」を代入。太字部分を追加します。

procedure TfrmCalc.btnKeisanClick(Sender: TObject);
var
  Num1 : Integer;
  Num2 : Integer;
  Ans : Double;
begin
  Num1 := StrToIntDef(edtInput1.Text, 0);
  Num2 := StrToIntDef(edtInput2.Text, 0);
  if lblEnzan.Caption = '+' then
    Ans := Num1 + Num2
  else if lblEnzan.Caption = '-' then
    Ans := Num1 - Num2
  else if lblEnzan.Caption = '×' then
    Ans := Num1 * Num2
  else if lblEnzan.Caption = '÷' then
    Ans := Num1 / Num2
  else
    Ans := Num1;
  edtInput2.Color := clYellow;
  edtKekka.Color := clWhite;
  edtKekka.Text := FloatToStr(Ans);
end;


ナッキー:このまま実行したらlblEqualに代入した「=」って見えないんでしたね。

高橋先生:lblEqualの「Visible」プロパティを「True」にすれば見えるようになるよ。

ナッキー:結果を表示するときは「=」は見えるほうがいいですね。


では、lblEqualの「Visible」プロパティを「True」に変更します(太字部分を追加)。

procedure TfrmCalc.btnKeisanClick(Sender: TObject);
var
  Num1 : Integer;
  Num2 : Integer;
  Ans : Double;
begin
  Num1 := StrToIntDef(edtInput1.Text, 0);
  Num2 := StrToIntDef(edtInput2.Text, 0);
  if lblEnzan.Caption = '+' then
    Ans := Num1 + Num2
  else if lblEnzan.Caption = '-' then
    Ans := Num1 - Num2
  else if lblEnzan.Caption = '×' then
    Ans := Num1 * Num2
  else if lblEnzan.Caption = '÷' then
    Ans := Num1 / Num2
  else
    Ans := Num1;
  edtInput2.Color := clYellow;
  edtKekka.Color := clWhite;
  lblEqual.Visible := True;
  edtKekka.Text := FloatToStr(Ans);
end;


これでほとんど完成ね。保存して実行してみましょう。計算結果まで出るようになりました。

Hide image
04計算ボタン完成

図04計算ボタン完成

高橋先生: edtInput1やedtInput2には、漢字など、数字以外も入力可能になっているので、入力できないように設定を変えよう。「Enabled」プロパティはコンポーネントが使用できるかどうかを設定するプロパティだよ。Falseだと使えない。「使えない」っていうのは画面上に表示されて入るけれど入力などを受け付けない状態。

ナッキー:では、edtInput1などのEnabledプロパティを設定するんですね。

高橋先生: Panel1のEnabledプロパティをFalseに設定することで、上に載っているコンポーネントをすべて同じ設定にすることができるんだ。

ナッキー:エディットの設定なのにパネルで指定するんですか?

高橋先生: コンテナコンポーネントは、上に載せているコンポーネントとの間に親子関係がある。だから、コンテナコンポーネントのことを親コンポーネント、載っているコンポーネントのことを子コンポーネントと呼ぶこともあるよ。親コンポーネントの性質が子コンポーネントに影響を与えることがあるんだ。このEnabledプロパティも影響を与える性質のひとつだね。

Hide image
05親子関係

図05親子関係


フォームデザイナの画面に切り替えてPanel1を選択します。オブジェクトインスペクタの[プロパティ]ページで「入力」の「Enabled」プロパティを「False」にします。保存して実行してみます。入力ができないことを確認しましょう。

    コピーボタンでイベントハンドラの呼び出し

ナッキー:これで完成ね!

高橋先生: いやいや、もうちょっと、がんばろう。演算ボタンのほかにいくつかボタンがついているね。こういうボタンはプログラムの使いやすさにつながるよ。

まずはクリアボタンから作業する。エディットやラベルに記述したものを消そう。消す方法は覚えてる?

ナッキー:えっと、Delete?

高橋先生: …。じゃあ、もう一回説明するよ。「長さ0の文字列」って言ったら思い出しくれるかな?シングルコーテーションを2つ('')並べて記述する。これは文字が入っていないという状態を表すんだったね。この「長さ0の文字列」を、エディットのTextプロパティに代入すると、表示されている文字列が空っぽに置き換わるんだ。

ナッキー:こんな感じですか?

edtInput1.Text := '';

高橋先生:そうだね。ほかにedtInout2、lblEnzanにも長さ0の文字列を代入する。lblEqualはVisibleプロパティをFalseにして見えなくしよう。さらに、エディットの色を最初の状態に戻そう。edtInput1は白、edtInput2とedtKekkaは黄色にしてね。


フォームデザイナの画面でbtnClearボタンを選択します。オブジェクトインスペクタの[イベント]ページで、「入力」の「OnClick」をダブルクリックします。

イベントハンドラの枠ができたら、コードを記述します。太字部分を書き加えてください。

procedure TfrmCalc.btnClearClick(Sender: TObject);
begin
  edtInput1.Text := '';
  edtInput1.Color := clWhite;
  edtInput2.Text := '';
  edtInput2.Color := clYellow;
  edtKekka.Text := '';
  edtKekka.Color := clYellow;
  lblEnzan.Caption := '';
  lblEqual.Visible := False;
end;

作成できたら保存して実行しましょう。一度計算結果を出してから、[クリア]ボタンをテストしてみます。ちゃんと消えました。これで何度でも計算できますね。

ナッキー:今度はコピーボタンですが、何をコピーするんですか?

高橋先生: ナッキーはAとBを足した結果にCを掛けたいってことはない?そんなときedtKekkaに出した答えをコピーしてedtInput1に入力できたら便利だよね。

ナッキー:edtKekkaの内容をedtInput1に代入するんですね。

高橋先生:普通に代入でもできるんだけど今回はメソッドを使ってみようよ。「メソッド」って覚えてる?第4回 画面もコードもすっきりさせようで説明したんだけど。

ナッキー:えへへへ。

高橋先生:…。メソッドはコンポーネントが持つ特有の関数やプロシージャのことだね。ほかの関数やプロシージャと違うのは、コード上で呼び出すときにコンポーネント名が必要な点。

コンポーネント名.メソッド名(パラメータ);

となる。今回はTEditが持つTextプロパティの内容をコピーするメソッドを使おう。まず、edtKekkaの文字列を全部選択した状態にする。

edtKekka.SelectAll;

これで、コピーの準備ができた。

Windowsでコピーは、文字列を「クリップボード」と呼ばれる一時保存場所にとっておく作業をいう。クリップボードでは原則上書きで保存しているよ。コードは

edtKekka.CopyToClipboard;

コードはこれだけ。パラメータはないから()も省略できる。

ナッキー:メソッドはTListBoxで使ったことがあったっけ。内容を一時保存の「クリップボード」に保存したあとはどうするの?

高橋先生:今度はクリップボードからTextプロパティに貼り付けするメソッドを使おう。

edtInput1.PasteFromClipboard;

これで貼り付けができるよ。コピーすれば、違うプログラムに貼り付けて使うことができるようになる。

Hide image
06クリップボード

図06 計算結果のコピー


フォームデザイナ画面でbtnCopyを選択します。オブジェクトインスペクタの[イベント]ページで「入力」の「OnClick」をダブルクリックしてイベントハンドラの枠を作成します。太字部分を記述しましょう。

procedure TfrmCalc.btnCopyClick(Sender: TObject);
begin                                                     
  edtKekka.SelectAll;
  edtKekka.CopyToClipboard;
  edtInput1.PasteFromClipboard;
end;

ナッキー:これでOKですね。

高橋先生: それだけだとedtInput1やedtInput2に以前の値が残っていたりするから、クリップボードにコピーしたあとクリアボタンをクリックしたときと同じ動きをさせよう。

ナッキー:ということは、btnClearClickイベントハンドラをコピーすればいいんだ。

高橋先生:それでもできるけど、あるイベントハンドラの中で、別のイベントハンドラを呼び出すことができるんだよ。

ナッキー:btnCopyClick の中でbtnClearClickを呼び出すんですか?

高橋先生:別のイベントハンドラを自分で呼び出すには、パラメータが必要なんだけど、それには「Sender」を使ってね。Senderには、イベントハンドラが呼び出される原因を作ったコンポーネントが入っているんだ。

以前プロシージャを使ったときパラメータに数値を入れてcase文を作成するのに使ったね。もう一度プロシージャでのパラメータの役割をみてみよう。

procedure SamplePro(Para : string);
begin
  ShowMessage(Para);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  SamplePro('Hello');
end;

実行してButton1ボタンをクリックしたとき、メッセージボックスに「Hello」と表示するコードだよ。パラメータとして「'Hello'」がSampleProプロシージャに渡される。SampleProでは「Para」として「'Hello'」を扱ってるね。Senderパラメータも同じように使われるよ。イベントハンドラの1行目を見てみよう。

procedure TForm1.Button1Click(Sender: TObject);

通常のイベントでは自動的に、イベントをおこしたコンポーネントがSenderに入っている。例えばbtnClearClickの場合Senderに入っているのは「btnClear」だね。一方、任意で呼び出した場合はコード上でパラメータにコンポーネントを入れてやらなければならない。そこでSenderをそのまま、ほかのイベントハンドラを呼び出すときのパラメータとして使うんだ。

procedure TfrmCalc.btnCopyClick(Sender: TObject);
begin
  btnClearClick(Sender);
end;

では記述するコードを考えていこう。btnClearClickイベントハンドラを呼び出す場所は、edtKekkaの内容をクリップボードにコピーしてからクリアして、edtInput1に代入するので以下のようになる。

edtKekka.CopyToClipboard;
btnClearClick(Sender);  //ココ
edtInput1.PasteFromClipboard;

順番を間違うと、コピーしたいものが消えていたり、貼り付けたあとでクリアしてなくなったりするから気をつけてね。

ナッキー:入れ子状態になっているから難しいですね。そもそもSenderパラメータが勝手に入ってくることにびっくりしました。


では、コードを書いちゃいます。edtKekkaの内容をコピーして、全体をクリア、edtInput1に貼り付けるということね。太字部分を追加します。

procedure TfrmCalc.btnCopyClick(Sender: TObject);
begin
  edtKekka.SelectAll;
  edtKekka.CopyToClipboard;
  btnClearClick(Sender);
  edtInput1.PasteFromClipboard;
end;

保存して実行してみましょう。一度結果が出るまで計算します。次に[コピー]ボタンをクリック。さらに演算ボタンを選んで2つ目の値をテンキーから入力してみてください。1度目の結果を使って演算することができます。実行を終了したら、コードエディタやメモ帳などで貼り付けを行ってみます。コピーした内容が貼り付けできますね。

ナッキー:やったー、これで完成ですね。

高橋先生: じゃあ、あと1つ。[閉じる]ボタンを作っておこう。プログラムを終了させるボタンだけどコードは簡単。

Close;

これだけでいい。メインとなるフォームを閉じるとプログラムが終了するんだ。


もうひとふんばりね。btnExitボタンを選択して、オブジェクトインスペクタの[イベント]ページから「入力」の「OnClick」イベントを作成。太字部分を追加します。

procedure TfrmCalc.btnExitClick(Sender: TObject);
begin
  Close;
end;

やっとできたわ。保存して実行します。[閉じる]ボタンを確認します。

Hide image
07完成図

図07完成図

ナッキー:ボタンは一通り作りました。今度こそ完成ですね。

高橋先生:うまく動かないときもあるよ。次回はそういうエラーの対処法を詳しく見ていこう。それにコードも多くて読みづらいからまとめてキレイにしようね。

ナッキー:前は、読みやすくするのに変数を使いました。

高橋先生:ほかにもいろいろあるよ。さらにグレードアップ目指そうね。

ナッキー:いろいろ??読みやすくすると何がいいんですか?

高橋先生:プログラムを使っていると、使いやすくしたいとか、ほかのプログラムに応用したいとか、もう一度コードを見る機会って案外あるんだよ。それが大概半年~数年経ってから機会がめぐってくることになる。すると読みにくいコードではそれだけで時間がかかったり、もう始めから作ったほうが早かったりするんだ。だから読みやすいコードで、修正もしやすくつくると、長い間使えるプログラムなる。来春は計算機プログラムもナッキーもグレードアップだ!

ナッキー:…。高橋先生、盛り上がりすぎですって。


ナッキーの「Turbo Delphiはじめて奮戦記」

Prev | Next | Index


Server Response from: ETNASC01