作者別: chie

PHP埋め込みテスト

外部に置いたphpファイルがうまく表示されません。
だいぶ前にPHPで作ったカレンダーを入れてみたのですが、ダメみたい。

なぜこんなことをやっているのかというと、DelphiでPHPを作ってみたいのです。
サイトで動くことは確認しましたが、WordPress上で動かすのは難しいです。
Delphiで作ったものをうまくインクルードさせることはできませんでしたが、外部phpは次の方法で表示できました。
ブログのテーマと同じフォルダに「calendar.php」があります。

<?php
  include TEMPLATEPATH . '/calendar.php';
?>

Warning: include(/home/zoomyc/www/blog/wp-content/themes/govpress/calendar.php): failed to open stream: No such file or directory in /home/zoomyc/www/blog/wp-content/plugins/exec-php/includes/runtime.php(42) : eval()’d code on line 17

Warning: include(): Failed opening ‘/home/zoomyc/www/blog/wp-content/themes/govpress/calendar.php’ for inclusion (include_path=’.:/usr/local/php/5.6/lib/php’) in /home/zoomyc/www/blog/wp-content/plugins/exec-php/includes/runtime.php(42) : eval()’d code on line 17

Fontの扱い

Delphi XE6 を初めて使ってみます。
教材がとても古いので、(Delphi 2)使えるかどうかわかりませんが、とりあえずやってみます。

procedure TForm2.Button1Click(Sender: TObject);
begin
  Canvas.Font.Color := clRed;     //文字色
  Canvas.Font.Size  := 20;        //サイズ
  Canvas.Font.Name  := \'MS 明朝\'; //書体
  Canvas.TextOut(10,10,\'20Point MS明朝\'); //文字の描画

  Canvas.Font.Color := clBlue;    //文字色
  Canvas.Font.Size  := 16;        //サイズ
  Canvas.Font.Name  := \'Times New Roman\';           //書体
  Canvas.Font.Style := [fsBold,fsStrikeout];        //文字のスタイル
  Canvas.TextOut(10,60,\'16Point Times New Roman\'); //文字の描画

end;

【結果】
xe3

Fontプロパティ

TFont 型のオブジェクトです。CanvasのTextOutメソッドを使って、指定したフォントで文字を描画できます。

Color 文字の色
Height 文字の高さ
Name フォント名
Pitch 文字ピッチ
Size 文字サイズ
Style 文字の形

 

FontのStyleプロパティ

fsBold 太字
fsItalic 斜体
fsUnderline 下線付き
fsStrikeout 取り消し線
fsBold,fsItalic,fsStrikeout 斜体、下線、取り消し線

Delphi2006で作ったプログラムが使えました。
ほかのプロパティも使えるのかな?
楽しみ~

xe4

Canvasを使う

Canvasとは

Canvasは、Delphiでグラフィクスを描画できるオブジェクトです。
独立したオブジェクトではなく、他のオブジェクトのプロパティとして存在します。

【Canvasプロパティを持つコンポーネント】
次のようなものがあります。

TBitmap,TComboBox,TDBComboBOx,TDBGrid,TDBListBox,TDirectoryListBox,TDrawGrid,TFileListBOx,TForm
TImage,TListBox,TPaintBox,TPrinter,TStringGrid

Canvasの機能

WindowsAPIのGDI関数を使ってグラフィクスを描画するには、次のような手順を踏みます。

  1. デバイスコンテキストの取得
  2. 描画ツールの作成
  3. 描画に使うペンの太さや色などを設定する
  4. グラフィックの描画
  5. デバイスコンテキストの復元
  6. デバイスコンテキストの解放
    ※デバイス コンテキストは表示やプリンターなどのデバイスの描画の属性についての情報を含むウィンドウのデータ構造です。 すべての描画の呼び出しは行、グラフィックスとテキストを描画するための Windows API をカプセル化するデバイスコンテキスト オブジェクトを介して行われます。

Canvasのプロパティ

Canvasには、描画に必要なプロパティがいろいろと用意されています。よく使われるものには次のようなものがあります。

  • 線を引いたり、長方形や円の描画に利用するPenプロパティ
    Color → 描画に使用する色を定数で指定します。
    Mode → キャンバスに描画するときのモード
    Style → 実線、破線、点線など、線の種類を指定
    Width → 線の幅
  • 塗りつぶしに利用するBrushプロパティ
  • 文字の描画に利用するFontプロパティ

Colorプロパティ

描画に使用する色を定数で指定します。(一覧がこちらのページにあります)
例:Canvas.Pen.Color := clRed;

【Modeプロパティ】

キャンバスに描画するときのモードを定数で指定します。
例えば、ModeプロパティがpmCopyのときには、Colorプロパティに指定した色になりますが、pmBlackを指定すると、Colorプロパティの値にかかわらずつねに黒で描画されます。
WindowsAPを使って描画モードを設定する場合は、SetROP2関数を使います。

【サンプル】

procedure TForm1.Button1Click(Sender: TObject);
begin
  Canvas.Pen.Color := clYellow;     //黄色いペンを指定
  Canvas.Pen.Mode := pmBlack;       //常に黒で描画するモード
  Canvas.TextOut(10,10,'pmBlack');  //説明文
  Canvas.MoveTo(100,20);            //開始位置
  Canvas.LineTo(200,20);            //この位置まで線を引く
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Canvas.Pen.Color := clRed;       //ペン色を指定
  Canvas.Pen.Mode := pmCopy;       //プロパティで指定した色で描画する
  Canvas.TextOut(10,30,'pmCopy');  //説明文
  Canvas.MoveTo(100,40);           //開始位置
  Canvas.LineTo(200,40);           //この位置まで線を引く
end;

 【実行結果】

ren26

【Modeプロパティ】

pmBlack 常に黒
pmWhite 常に白
pmNop Canvasには何も描画されない
pmNot 画面色の反転色
pmCopy Colorプロパティで指定したペン色
pmNotCopy ペン色の反転色
pmMergePenNot  ペン色と画面反転色の組み合わせ
pmMaskPenNot  ペン色と画面反転色の組み合わせに共通な色との組み合わせ
pmMerge  ペン色と画面色の組み合わせ
pmNotMerge  pmMergeの反転
pmMask  ペン色と画面色の両方に共通な色との組み合わせ
pmNotMask  pmMaskの反転
pmXor  ペン色と画面色の組み合わせで両方に共通した色を除く
pmNotXor  pmXorの反転

【Styleプロパティ】

描画する線の種類を定数で指定します。

psSolid 実線
psDash 破線
psDot 点線
psDashDot 一点鎖線
psClear 見えない線
psLnsideFrame 閉じた図形の枠内に線を描画

【サンプル】 Styleプロパティのサンプル

procedure TForm1.Button1Click(Sender: TObject);
begin
  Canvas.Pen.Style := psDot;      //点線のスタイル
  Canvas.MoveTo(100,20);          //開始位置
  Canvas.LineTo(200,20);          //この位置まで描画

  Canvas.Pen.Style := psSOLID;    //実線のスタイル
  Canvas.MoveTo(100,40);          //開始位置
  Canvas.LineTo(200,40);          //この位置まで描画

  Canvas.Pen.Style := psDashDot;  //一点鎖線のスタイル
  Canvas.MoveTo(100,60);          //開始位置
  Canvas.LineTo(200,60);          //この位置まで描画
end;

【実行結果】

ren27

【Brushプロパティ】

Color 塗りつぶしの色
Style 塗りつぶし模様の種類
Bitmap 塗りつぶしに利用するビットマップイメージ

 【模様の種類】

bsSolid べた塗り
bsClear  塗りつぶしなし
bsBDiagonal 右上がり45度の斜線
bsFDiagonal 右下がり45度の斜線
bsCross 格子
bsDiagCross 斜線の格子
bsHorizontal 水平線
bsVerical 垂直線

【Brushプロパティのサンプル】

procedure TForm1.Button1Click(Sender: TObject);
begin
  canvas.Brush.Style := bsSolid;            //べた塗り
  Canvas.Brush.Color := clRed;              //色を設定
  Canvas.Rectangle(100,10,100+30,10+30);    //長方形の描画

  Canvas.brush.Style := bsCross;            //格子スタイル
  canvas.Brush.Color := clBlue;
  Canvas.Rectangle(100,50,100+30,50+30);    //長方形の描画
  end;

【実行結果】

ren28

配列の引き渡し

値パラメータとして配列を渡す

配列の受け渡しには、オープン配列パラメータを使います。オープン配列パラメータとは、異なるサイズの配列を同じ手続き、又は関数に渡せることを言います。

引数のデータを指定するときには、「array of データ型」のように記述します。
配列の添え字は、実引数で「array[1..10]of Integer」のように指定した場合、先頭は1になりますが、仮引数では「0」が配列の先頭要素となります。

【サンプル】

procedure TForm1.Button1Click(Sender: TObject);  //ボタンクリック
var
  arrA       : array[1..10] of Integer; //配列の宣言
  i          : Integer;                 //ループのカウント
begin
  for i := 1 to 10 do  begin             //1から10までループ
    arrA[i] := i;
  end;{for}                             //カウンタの数値を配列に代入
  Keisan(arrA);                         //配列を呼び出す
end;

procedure Keisan(A : array of Integer); //手続き
var
  i,Kotae : Integer;
  begin
    Kotae := 0;                         //仮引数の添え字は0から
    for i := 0 to 9 do begin            //カウンタの値を足す
      Kotae := Kotae + A[i];
    end;{for}                           //メッセージボックスに答えを表示
      ShowMessage(IntToStr(Kotae));
  end;

【実行結果】

ren25

変数パラメータとして配列を渡す

変数パラメータの場合は、呼ばれる側の手続き(関数)で、仮引数の前に予約語varを記述します。
配列の添え字の上限は、High関数で取得できます。
【サンプル】

procedure TForm1.Button1Click(Sender: TObject);  //ボタンクリック
var
  arrA       : array[1..10] of Integer; //配列の宣言
  i          : Integer;                 //ループのカウント
begin
   Keisan(arrA);                        // 手続きの呼び出し
  for i := 1 to 10 do  begin            //1から10までループ
     ShowMessage(IntToStr(arrA[i]));    // 配列の値を表示
  end;{for}                             //カウンタの数値を配列に代入
end;

procedure Keisan(var A : array of Integer); //仮引数の前にvarをつける
var
  i : Integer;
  begin
    for i := 0 to High(A) do begin        //Hige()は添え字の最終値を取得
      A[i] := i+1;                        //個々の配列に1から10の値代入
    end;{for}
  end;

 

パラメータの受け渡し

手続きや関数では、パラメータを渡して処理をすることがあります。
呼び出す側で指定するパラメータを実引数、呼ばれる側のパラメータを仮引数と言います。
※実引数と仮引数の変数名は同じでなくてもよい

  intMenseki := Menseki_keisan(intTate,intYoko);  //赤い文字は実引数(呼び出す側)
  Edit3.Text := IntTOStr(intMenseki);

end;

function Menseki_keisan(intTate, intYoko : Integer) : Integer; //青い部分は仮引数(呼び出される側)
  begin
    Menseki_keisan := intYoko * intTate;                       
  end;
  • Delphiのパラメータには、値パラメータ、変数パラメータ、定数パラメータの3種類があります。
  • 値パラメータは、ローカルパラメータなので、仮引数で変更した内容は実引数に影響を与えません。
    procedure TForm1.Button1Click(Sender: TObject);//ボタンクリック
    var
      intA,intB : Integer;
    begin
      intA := 10;          //値を代入
      intB := 20;
      Tashizan(intA,intB); //手続きの呼び出し、値10と20を渡す。
    end;
    
    procedure Tashizan(intA,intB:Integer);//手続き (仮引数)
    begin
      Form1.Edit3.Text := IntToStr(intA + intB);//引き渡された値で計算
    end;
  • 変数パラメータは、仮引数で変更した内容は実引数に影響します。
    引数を変数パラメータとして渡すには、呼ばれる側の手続き(関数)で、仮引数の前に予約語varを記述します。
    実引数の初期値には、仮引数の値が使われます。

    【サンプル】

    procedure Tashizan(var intA,intB :Integer);   //手続き (仮引数)
    begin
       intA := intA * 2;                          //仮引数(値を変更)
       intB := intB * 2;                          //仮引数(値を変更)
    
    end;
    procedure TForm1.FormCreate(Sender: TObject);
     var
        A,B : Integer;
    begin
      A := 10;                          //実引数
      B := 20;                          //実引数
      Form1.Edit1.Text := IntToStr(A);
      Form1.Edit2.Text := IntToStr(B);
    
      Tashizan(A,B); //手続きの呼び出し、値10と20を渡す。
      Form1.Edit3.Text := IntToStr(A + B); // 結果を表示
    end;

    【実行結果】 ちょっとヘンなサンプルですけどぉ(^^;
    ren24

関数

関数

引数と呼ばれるデータを受け取り、定められた通りの処理を実行して結果を返す一連の命令群。多くのプログラミング言語では、関数がプログラムを構成する要素となっている。多くの言語や処理系では、開発者の負担を軽減するため、よく使う機能が関数としてあらかじめ用意されている。
例えば「二つの数を受け取って、それらを合計した結果を返す」という命令は関数である。この関数をfと呼ぶとすると、「関数fに引数1と2を与えると3という結果が返ってくる」ということになる。(IT用語辞典より)

  • Delphiで処理の結果を返す関数を作成するには、予約語functionを使います。
  • 関数のヘッダ部分には、関数の名前と戻り値のデータ型、必要であれば引数を()で囲んで指定します。
    【書式】

    function <関数名>:<戻り値の型>;
    function <関数名>:(<引数1>:<型1>; <引数2>:<型2>;...):<戻り値の型>;
  • 関数は、値を返すため、関数の処理の中で戻り値の代入先を指定する必要があります。

【サンプル】 面積を計算する部分を関数にしました。

var
  Form1: TForm1;
  function Menseki_keisan(intTate,intYoko : Integer) : Integer;//関数の宣言

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
    intTate, intYoko  : INteger;
    intMenseki        : Integer;                  //戻り値を代入する変数

begin
  intTate := StrToINt(Edit1.Text);                //縦の値
  intYoko := StrToINt(Edit2.Text);                //横の値
  intMenseki := Menseki_keisan(intTate,intYoko);  //関数を呼び出す
  Edit3.Text := IntTOStr(intMenseki);

end;

function Menseki_keisan(intTate, intYoko : Integer) : Integer; //関数定義
  begin
    Menseki_keisan := intYoko * intTate;                       //面積計算
  end;

【実行結果】
ren23

手続き

手続き

  • プログラム内で繰り返し出現する処理を行うために、一連の命令を一つの手順としてまとめたものを、プロシージャと言います。「手続き」とも呼ばれ、プログラム内部での処理単位の一つとして扱われます。
  • プロシージャを実行することを「プロシージャを呼び出す」と言います。
  • Delphiのコードはほとんどがイベントハンドラに記述されますが、どのイベントに属さない独自処理の場合、「手続き」や「関数」として、作成することができます。
  • 「手続き」や「関数」として、作成した場合、利用する前にinterface部に作成した手続きや関数が宣言されているかどうかを確認します。
  • 手続を作成するには、予約語procedureを使います。
  • 手続きは、ヘッダ部宣言部コード部の3つに分類されます。
    ren21
  • 手続きのヘッダー部分には、手続きの名前と、引数(必要な場合)を、カッコ()で囲んで指定します。
    引数を指定する場合は、名前とデータ型を「」(コロン)で区切って指定します。
  • 複数の引数を指定する場合は、「」(セミコロン)で区切って指定します。

【書式】

procedure <手続き名>
procedure <手続き名>(<引数1>:<型1>;<引数2>:<型2>;...);

【サンプル】

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);//Delphiが作った手続き
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  procedure Tashizan(intA,intB : Integer); //自分で作った手続の宣言

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  intA,intB : Integer;
begin
  intA := StrToInt(Edit1.Text);//Edit1に入力した値
  intB := StrToInt(Edit2.Text);//Edit2に入力した値
  Tashizan(intA,intB);         //手続きの呼び出し
end;

procedure Tashizan(intA,intB:Integer);//手続き
begin
  Form1.Edit3.Text := IntToStr(intA + intB);//計算結果
end;
end.

【 実行結果】

ren22

繰り返し

指定した条件を満たしている間、または条件になるまでの間、繰り返して同じ処理を行うことをループ処理といいます。
繰り返す回数があらかじめ分かっている場合は「for..to」を使用します。
回数がわからない場合は、「while…do」または「repeat…until」を使います。

for文

  • for…to…do は、指定した初期値からカウンタを1つずつ増やしながら、最終値になるまで、do以降の処理を実行します。
  • for…downto…do は、カウンタを1つずつ減らしながら処理を行います。初期値は、最終値よりも大きい必要があります。
  • begin…end を使って、ブロックを明確にします。

【サンプル】 5回の繰り返し(for…to…do)

procedure TForm1.Button1Click(Sender: TObject);
var
  i         : Integer;  //ループのカウンタ

begin
   Memo1.clear;
   for i:=1  to 5 do    //カウンタが1から5の間
                        //begin...end の処理を繰り返す
   begin
       Memo1.Lines.Add(IntToStr(i)); //カウンタの値を表示
   end;

end;

 

while文

  • while…do は、指定した条件が満たされている間(True)、do の直後のブロック処理を実行します。
  • 条件式は、ブロックの処理を行う前に評価されます。条件に満たない(False)場合は、ループに入りません。

【サンプル】 5回のループ。前の答えに、ループのカウントを加算しています。

procedure TForm1.Button1Click(Sender: TObject);
var
  i         : Integer;  //ループのカウンタ
  intAns    : Integer;  //答えの数値

begin
  i := 1;               //初期値を変数に代入
  intAns := 0;          //初期値を変数に代入

  while i <=5  do       //カウンタが5以下なら begin...endの間を繰り返す
    begin

      intAns := intAns + i ; //答えにiの値を加算
      Memo1.Lines.Add('i =  '  + IntToStr(i) + ' → ' + IntToStr(intAns));
      i := i + 1;       //カウンタの値を1増やす
    end;
end;

【実行結果】

答えの初期値はゼロなので、0+1=1です。2順目はその1にカウント2を足して3になります。

ren18

repeat文

  • repeat…until は、until文で指定した条件が満たされるまで(Falseの間)、repeat の直後のブロックを実行します。
  • 条件式は、ブロックの処理を行った後に評価されます。ループは必ず一度は実行されます。

【サンプル】 結果はWhile文と同じです

procedure TForm1.Button1Click(Sender: TObject);
var
  i         : Integer;  //ループのカウンタ
  intAns    : Integer;  //答えの数値

begin
  i := 1;               //初期値を変数に代入
  intAns := 0;          //初期値を変数に代入

  repeat
    begin
      intAns := intAns + i ; //答えにiの値を加算
      Memo1.Lines.Add('i =  '  + IntToStr(i) + ' → ' + IntToStr(intAns));
      i := i + 1;       //カウンタの値を1増やす
    end;
    until i > 5;        //iの値が5を超えるまで処理を継続(False)
                        //iの値が5を超えたら処理を終える(True)
end;

 

ループからの脱出

  • ループ構造から脱出する手続きとして、break continue があります。
    break手続きはループから脱出します。
    continue手続きは、ループの先頭に戻って処理を継続します。

【サンプル】

procedure TForm1.Button1Click(Sender: TObject);
var
  i         : Integer;  //ループのカウンタ
  intAns    : Integer;  //答えの数値
  intRet    : Integer;  //ダイアログボックスの戻り値
begin

  intAns := 0;          //初期値を変数に代入

  for i := 1 to 10 do
  begin
    Memo1.clear;
    intAns := intAns + i;
    Memo1.Lines.Add('i =  '  + IntToStr(i) + ' → ' + IntToStr(intAns));
    intRet := MessageDlg('続けますか?',mtConfirmation,[mbYes,mbNo],0);

    if intRet = mrYes  then  //「はい」ボタンがクリックされたら
      Continue               //ループの先頭から処理を継続
    else                     //「いいえ」がクリックされたら
      break;                 //ループから脱出する
  end;

  ShowMessage('終了');
end;

【実行結果】「はい」をクリックで続き、「いいえ」をクリックすると、終了します。

ren19

条件判断

「もし状況がAだったら処理Xを実行し、もし状況がBだったら処理Yを実行する」
このように、状況に応じて処理を選択する手法を条件分岐と呼びます。

if…then…else

もっともよく使われる条件判断です。次の点に注意します。

  • elseの前の文末にはセミコロンをつけない
  • 条件が満たされたときに実行される処理を、begin..end ブロックで囲む
  • ifの後の式(論理式)が複数の場合は、カッコ()でくくる

【構文】

if <式> then <文1> else <文2>

【例】

if 論理式 then begin
  文
  文
 ...
end;

【サンプルプログラム】

implementation

{$R *.dfm}
  var
    intFlg : Integer;//ユニット内変数の宣言

procedure TForm1.Button1Click(Sender: TObject);

begin
  if intFlg = 0 then          //変数intFlgが0のとき
    begin
      Form1.Color := ClBlack;//フォームが黒色
      intFlg := 1;           //intFlgに1を代入
    end                      //elseの直前なのでセミコロンはつけない
  else                       //intFlgが0以外のとき
    begin
      Form1.Color := ClWhite;//フォームが白色
      intFlg := 0;           //intFlgに0を代入
    end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    intFlg := 0;  //変数の初期化
end;

end.

【実行結果】 ボタンをクリックするごとに色が切り替わります

ren15ren16

 

case文

  • 複数の条件を指定する場合、if文でも分岐することはできますが、case文を使うほうがプログラムが読みやすくなります。
  • 条件が満たされたときに実行する処理を、begin…endブロックで囲みます。
    ※ブロック内の処理が1文だけのときにはbegin…endブロックで囲む必要はありません。
  • case文を使う場合は、elseの直前の文にもセミコロンが必要です。

【書式】

case <式> of
   値1: ...文1;
   値2: ...文2;
   ...
   else ...それ以外の処理;
end;

【サンプル】

  //性別をチェックする
     case RadioGroup1.ItemIndex of
      0 : sex := male;
      1 : sex := female;
      else
        ShowMessage('性別を入力してください');
     end;

【サンプル】

procedure TForm1.Button1Click(Sender: TObject);
var
  intNo  : integer;   //Editコンポーネントに入力された値
  strMsg : String[10];//メッセージボックスに表示する文字
begin
  intNo := StrToint(Edit1.Text);//Editコンポーネントの値を代入(整数に変換)
  case intNo of
    3..5  : begin
            strMsg :='春';
            ShowMessage(strMsg);
            end;
    6..8  : begin
            strMsg :='夏';
            ShowMessage(strMsg);
            end;
    9..11 : begin
            strMsg :='秋';
            ShowMessage(strMsg);
            end;
    12,1,2 :begin//12..2のように指定すると下限が上限を超えるのでエラーになる
            strMsg :='冬';
            ShowMessage(strMsg);
            end;
    else
      begin
        strMsg :='エラー';
        ShowMessage(strMsg);
      end;
  end;
end;

【実行結果】 月を入力しボタンをクリックします

ren17

ブロック

Delphiのブロック

  • Delphiでのプログラミングは「ブロック」の概念が重要です。もっとも一般的なブロックはイベントハンドラです。
  • ブロックは宣言部と実行部の2つで構成されますが、宣言部は省略可能です。
    procedure TForm1.Button1Click(Sender: TObject);
     var                       //ブロックの始まり・宣言部
        strTest:String[10];    //
    begin                      //実行部
      strTest :='Hello';
      Edit1.Text := strTest;
    
    end;                      //ブロックの終わり
  • Delphiでは、begin…end で囲まれた文で1つのブロックを構成します。
  • Delphiでは、if…then や else で実行するブロックも、begin…end が必要です。(1文の場合は必要ない)
    ブロックを構成する処理が2文以上ある場合は、必ずbegin…end で囲みます。上記は家にあった、古いDelphiの本を参考にしました。平成8年に技術評論社から出版された「Delphiテニクニックマスター2.0」という本です。今から18年も前に、Delphiってあったんだ・・すごいね~ 古いね~
    丁寧にわかり易く書いてあります。作者は谷尻かおりさん、VBAもこの方の本で勉強しました。
    たぶん、私が買ったんだわ。そして、無謀な挑戦にあきらめた(^^;
    【サンプル】

    procedure TForm1.btnTasuClick(Sender: TObject);
    //演算ボタン[+]が押されたとき
    begin
      //エラー処理(値がないのに演算ボタンをクリックしたとき
      if Edit1.Text = '' then
        raise Exception.Create('値を入力してから演算ボタンをクリックしましょう');
    
      if Edit2.Text <>'' then
        begin
          Edit2.Text := '';
          ShowMessage('値を入力してください');
        end;
    
      lblEnzan.Caption := '+';
      Edit1.Color := clYellow;
      Edit2.Color := clWhite;
    end;