Delphi入門

エディタは文字列処理が命!

編集のメニューをもう一度確認

さて、非常に大変だったと思いますが、 ファイル操作は慣れましたでしょうか?ハッキリ行って、ファイル操作は慣れです。 慣れればなんて事はありません。 また、この先々で、LoadFromFileが他のOSとの関係で不都合になってくる時がありますが、 その話は高度な(改行コードなど)の話になりますので、「Delphi Tips」を御覧になって下さい。

メインメニューの作成
元に戻す(mnuUndo)
操作を一手元に戻す
やり直し(mnuRedo)
操作を一手やり直す
切り取り(mnuCut)
選択された文字列をカットして、クリップボードへコピー
コピー(mnuCopy)
選択された文字列をクリップボードへコピー
貼り付け(mnuPaste)
クリップボードに格納されている文字列をカーソル位置へ貼り付ける
すべて選択(mnuSelectAll)
編集ドキュメントすべてを選択
日付の貼り付け(mnuGetDay)
日付を貼り付け
右端で折り返す(mnuWordWrap)
右端で折り返す
フォントの設定(mnuFont)
フォントの設定

()内は、各メニューのNameの値です。 前のファイル操作ではしませんでしたが、Visual Basicなどではこのように定める事が推奨されていて、 結構いいなと僕も感じたのでそうしました。 先ほども言いましたが、今回は実践してメニューの場合は、最初に「mnu」をつけて、後に分かりやすい英語を指定して名前を付けると良いです。 こういうのを「Prefix」(プレフィックス:接頭辞)などと言ったりします。

元に戻す

メモ帳などにはよくある機能です。 操作を戻します。これがないとエディタとして使えません。行った作業を一手戻すのは難しそうに見えますが… プログラムは非常に簡単です。以下のように書きます。

procedure TForm1.mnuUndoClick(Sender: TObject);
begin
   Memo1.Undo ;
end;

だけです。何と非常に簡単な… という感じですね。

やり直し

TMemoでは「やり直し」と「元に戻す」作業はセットで過去1回しかできません。 これは「Delphi」側がプログラムしているからではなく、Windowsのメモ帳がそのような仕様だからです。 つまり、Windowsの元からの仕様によって「Delphi」も変わってくると思って下さい。 詳しく話すのは後にして今はそう捉えてください。というので、次のプログラムでは動きません。 「Redo」が定義されていないからです。

procedure TForm1.mnuUndoClick(Sender: TObject);
begin
   Memo1.Redo ;
end;

ではどうすれば良いのか?と言いますと、 答えは、メモ帳を見てください。「元に戻す」と「やり直し」が交互に切り替わるはずですので、それを参考に作って見て下さい。 if文と、メニューのEnabledをうまく使えば行けます。

切り取り、コピー、貼り付け、削除

クリップボード関連を使う時にはちょっとした 注意が必要になります。

  • まず、これらを使うには「uses節」に「Clipbrd」というのを追加します
  • 「uses節」というのはプログラムの一番上の方に、「Form,Dialogs」などというのがあります
  • C言語の経験ある方は<stdio.h> <math.h>などと同じです
  • ここでどんな機能を使うかによって、「uses節」に追加する事も必要な時があります

「uses節」というのは重要です。 もちろん、言語には各役割を持ったものが存在します。最初からすべての情報を搭載していたのでは、 膨大な量になってしまいます。そこで、必要最低限の機能だけを使うようにしています。 プログラムの一番上の方に次のようなコードがあると思います。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs
  , Clipbrd ;

「Dialogs」というのがありますが、 これは主に「メッセージボックス」や「オープンファイルダイアログ」を制御するものと思って下さい。 「Form」は文字通り、「フォーム」を制御するものです。各役割が分担されていて、 用途に応じて呼び出すようにしているのです。

//切り取り
procedure TForm1.mnuCutClick(Sender: TObject);
begin
   Memo1.CutToClipboard ;
end;

//コピー
procedure TForm1.mnuCopyClick(Sender: TObject);
begin
   Memo1.CopyToClipboard ;
end;

//貼り付け(ペースト)
procedure TForm1.mnuPasteClick(Sender: TObject);
begin
   Memo1.PasteFromClipboard ;
end; 

//削除
procedure TForm1.mnuDelete(Sender: TObject);
begin
   Memo1.SelText := '' ;
end; 

となります。何となく分かると思いますが、 最後はちょっと分かりにくいので説明します。 「削除」というのは選択文字列を削除するというものです。 現在選択されているテキストは、「SelText」で取り出す事ができますので、これを「''」(空)にする事で、 選択されている文字列を空にするという事で削除する事ができています。

すべて選択

すべて文字を選択します。

procedure TForm1.mnuSelectAllClick(Sender: TObject);
begin
   with Memo1 do
   begin
      if SelLength = GetTextLen then
         SelLength := 0 else SelectAll ;
   end ;
end;

ちょっと工夫をしてみましょう。 ただ、すべてを選択されるのではメモ帳止まりになってしまいます。 すべて選択して、もし、すべて選択されている状態ならそれを解除するというのを考えてみます。 「with」というものが出てきました。「with」以下のプログラムを見てみると、Memo1が最初に抜けてます。 共通のものがある時はこの「with」で括ると見栄えが良くなります。ですから次のように書いても良いワケです。 尚、上のプログラムに置いて、一行で終わってますので、「with」文の「begin」〜「end」は別に必要ありません。

procedure TForm1.mnuSelectAllClick(Sender: TObject);
begin
   if Memo1.SelLength = Memo1.GetTextLen then
      Memo1.SelLength := 0 else Memo1.SelectAll ;
end;

「GetTextLen」というのは、 そのすべての文字列の長さを取得する関数です。 そして、「SelLength」というのは「SelText」と同じように、選択されている文字列の長さを返す関数です。 つまり、これにより、「すべて選択されている状態」というのを判別できますよね? そして、すべて選択されている状態ならば、反転(選択)を取り消し、そうでないならばすべてを選択します。 すべて選択の際には、「SelectAll」というものが使えます。

日付の貼り付け

これは殆ど覚えるしかありませんので覚えて下さい。

procedure TForm1.mnuGetDayClick(Sender: TObject);
begin
   ShortdateFormat := 'yyyy/mm/dd';
   Memo1.SelText := DateToStr(Date);
end; 

まず「shortdataFormat」というのはヘルプで調べて見て下さい。 「yyyy」とすると、西暦4桁で…という事ですね。 自分もそんなに詳しいワケではないので、毎回使うたびにヘルプを見ているような感じです。 そして、「SelText」つまり、選択された文字列に、日付を貼り付けるという事になります。

また、ひとつ忘れてましたが、 もし文字列が選択されてない時には「SelText」はどうなるのか?といいますと、 これはタダの現在位置に文字列を挿入する…というような事と同じ事になります。 これは非常に重要で、後々出てきます。「DateToStr」というのは「IntToStr」と同じです。 整数型などと同じように、「Data型」というのが定義されています。 この「型」は最初は慣れないかも知れませんが、そのうち慣れてきます。

右端で折り返す

メモ帳などでもありますように、右端で文字を折り返すような ものを考えて見ます。これも既存の手続きが用意されております。

procedure TForm1.mnuWordWrapClick(Sender: TObject);
begin
   if mnuWordWrap.Checked then
   begin
      {もし、右端折り返しになっていたら…}
      mnuWordWrap.Checked := False ;
      Memo1.WordWrap := False ;
   end else
   begin
      {もし、右端折り返しになっていなかったら…}
      mnuWordWrap.Checked := True ;
      Memo1.WordWrap := True ;     
   end ;
end;

「右端に折り返し」になっているかどうかは、 「WordWrap」というものが使えます。 「Memo1」の「オブジェクトインスペクタ」で「Lines」の所で適当に横に長い文章を編集して見て下さい。 そして、「WordWrap」の所を切り替えたりしてみると良く分かります。 というので、あまり詳しくは説明しません。

メニューにチェックを入れたい時には、 「mnuWordWrap.Checked := True ;」のようにすると、チェックが入ります。 「オブジェクトインスペクタ」で「Checked」の所を変えて見て下さい。これも良く分かると思います。 そして、今回はもっと簡単にプログラムを書けないか?というものですが、自分は次のように書いています。

procedure TForm1.mnuWordWrapClick(Sender: TObject);
begin
   mnuWordWrap.Checked := not mnuWordWrap.Checked ;
   Memo1.WordWrap := mnuWordWrap.Checked ;
end;

「Checked」というのは「チェックが入っているか(True)」「入っていないか(False)」というBoolean型(ブーリヤン型)です。 これに、「not」を付ける事で、切り替えができるようになります。 つまり、「not True」→「False」、「not False」→「True」ですので… これをうまく利用します。

フォントの設定

フォントの設定を行います。


procedure TForm1.mnuFontClick(Sender: TObject);
begin
  if FontDialog1.Execute then
  begin
     Memo1.Font.Name := FontDialog1.Font.Name ;
     Memo1.Font.Size := FontDialog1.Font.Name ;
     Memo1.Font.Style := FontDialog1.Font.Style ;
  end ;
end;

でできますが、面倒でしたら、次のようにしても構わないでしょう。


procedure TForm1.mnuFontClick(Sender: TObject);
begin
  if FontDialog1.Execute then Memo1.Font := FontDialog1.Font ;
end;

「Font」というものの中には、「Name」(フォント名)、「Size」(サイズ)、「Style」(スタイル:太字とか、イタリックとか…)という種類があります。 一個一個指定したい時もあるのでそういう場合には、前者の方法がベストです。 例えば、「フォントを大きくする」というメニューを見かけた事あると思いますが、 そういう時には、「Size」を大きくするワケです。 後者の方ですと、そういう場合には不便です。今はまだあまり気にしなくてもいいですが、

例えば、メモ帳を「太字」「イタリック」などに設定できなくするには、 後者の方法ではできませんので前者で「Name」と「Size」だけ指定するようにします。 詳しくはヘルプ見るといいですが、 結構見たら最初からはちょっと難しいようなコードですね(「Delphi5」の場合ですけど…)。 以上が「編集」の操作でした。「ファイル」に比べたら決まりなので簡単だとは思いますが…(笑)