MemoコンポーネントのModifiedプロパティを参照するだけでテキストの変更の有無をチェックすることができる。そこでファイルの保存とファイルを開く手続きの内容をもう少し丁寧に制御することにしよう。
Exit手続き:
ファイルの上書き保存(A)が選択されたとき,現在のファイルの内容が変更されていなければ保存する必要がないので,保存しない(何もしない)ように修正する。Exit手続きは, 現在の手続きから脱出してすぐ上位の手続きに制御を渡す。
また、ファイルを保存したら、ModifiedプロパティをFalseにリセットしなければならない。
〔上書き保存(A)〕のプログラムコードを次のように3行追加修正する。
〔上書き保存(A)〕のプログラムコード(その3)
procedure TForm1.FileSave1Click(Sender: TObject); begin if not Memo1.Modified then //*テキストが変更されていないとき, Exit; //*この手続きから抜ける if MyFilename = NewFilename then //新規ファイル名のままなら, FileSaveAs1Click(Sender) //名前を付けて保存を呼び出す else begin //それ以外は, Memo1.Lines.SaveToFile(MyFilename); //編集中のファイル名で保存する Memo1.Modified := False; //*保存したのでModifiedをFalseに戻す end; end;
名前を付けて保存の手続きは、その中で上書き保存を呼び出している。開いたり、保存したりした直後の”変更していない”テキストを複写するために”別の”名前を付けて保存しようとしても、このままでは上で追加した"Exit"文が働いて保存できない。 そこで、〔名前を付けて保存(A)〕のプログラムにおいて, FileSave1Click (Sender) を呼び出す直前に次の1行を追加しておこう。
〔名前を付けて保存(A)〕のプログラムコード(その3 -"一部分"-)
Caption := MyCaption + MyFilename; Memo1.Modified := True; //* 変更されたことにする FileSave1Click(Sender); // 上書き保存の手続きを呼び出す
メモ帳の編集画面にテキストを表示している時、この〔開く(O)〕メニューを選択した場合を考える。別のファイルを開いてメモ帳にロードするということは、現在編集中のテキストを失うことを意味する。そこで、終了処理の場合と同じように、編集中のファイルがあればその保存を確認する処理を追加する。
また、ファイルをメモ帳に読み込ん(ロード)だ直後は、ModifiedプロパティをFalseにリセットしておく。
〔開く(O)〕のプログラムコードを次のように修正(6行追加)する。メッセージには定数"Msg"を用いている。
このMessageDlg関数は下図のような警告メッセージダイアログを表示する。
Fig.3 警告
〔開く(O)〕のプログラムコード(その3)
procedure TForm1.FileOpen1Click(Sender: TObject); begin if Memo1.Modified then //* 変更されていれば警告ダイアログ case MessageDlg(Msg, mtWarning, mbYesNoCancel, 0) of mrYes: FileSave1Click(Sender); mrCancel: Exit end; if OpenDialog1.Execute then begin MyFilename := OpenDialog1.Filename; Caption := MyCaption + MyFilename; Memo1.Lines.LoadFromFile(MyFilename); Memo1.Modified := False; //* 読み込んだのでModifiedをFalseに戻す end; end;
この簡易版エディタ「メモ帳」では、 Delphiのメモ・コンポーネントのLoadFromFileとSaveToFileメソッドを使うことによってファイルの入力と出力を行なっている。 これらのメソッドは、実行中にエラーが発生するとユーザにエラーメッセージを表示して、自動的に最低限のエラー処理を行なってくれる。(Run Time Library, p.185) 例えば、LoadFromFileメソッドで存在しないファイル名"A:\Sample1.txt"を与えたとする、すると、「ファイルA:\Sample1.txtを開けません」というエラーメッセージと〔OK〕ボタンを含むSTOPダイアログボックスが表示される。 ユーザが〔OK〕を押せば、ファイルの入力をキャンセルして何事もなかったかのように処理を続けることができる。
しかし、これらのメソッドが処理してくれるのは、あくまでも汎用的な部分であって、各種応用ソフトウェアに固有な処理については面倒を見てくれない。応用ソフトウェアの完成度を高めるためには作成者がより詳細なエラー処理を記述する必要がある。 そのようなエラー処理を一貫した方法で行なうためには「例外処理」というプログラミング技法を使う。(p.186-188, p.197, p.269)
Delphi (Object Pascal)では、例外処理を行なうために専用のプロテクトブロック(保護区)try ... except ... end; を宣言する。 保護ブロック内で発生した特定または複数の例外を処理するコードを例外ハンドラという。例外ハンドラを定義するには、保護したいコードをtry部の中に埋め込み、except部に例外に対する処理文を記述する。
try部の文の実行中に例外が発生した場合にだけexcept部の文が実行される。 例外が発生しない場合は、except部の文は無視されて、次の実行制御はブロックの終りのend文に移る。 try部の処理文で例外が生成されると、すぐに実行がexcept部に移行し、現在の例外に適用される特定の例外ハンドラ(on ... do文)を見つけてその例外ハンドラのdo部の文が実行される。 その後、実行は現在のブロックの終りのend文から続行される。