Delphi日記

第7章 ファイル保存確認の追加(11/25/01)

今回は新たなファイルを新規作成・開く時、あるいは終了するとき、編集中のファイルを保存するかどうかの確認作業を追加します。今の状態では編集中のファイルを保存せずに新規作成・開く・終了すると、確認なしに編集中のファイルを破棄してしまいます。これを修正します。今回はコードの編集が多いので紛らわしいかもしれません。

Unit1.pasウインドウの中で、第3章で{ Public 宣言 }と書いてあるところに「FileName: String;」と追記しましたが、更にそのFileName: String;の下に

isChange: Boolean;

と入力します。


これはテキストが変更されたかどうかを判断する変数です。trueの時が変更がしてある状態、falseの時が変更をしていない状態をあらわすようにしたいので、変更されたときにtrueに設定されるようにします。
オブジェクトインスペクタでTMemo1を選択し、イベントタブの下の「OnChange」の白い部分をダブルクリックします。 ユニットファイル(Unit.pas)のウインドウに現れた
procedure TForm1.FormCreate(Sender: TObject);
のbeginとend;の間に

isChange := true;

と入力します。isChangeはファイルが保存されたとき、新規作成されて無編集の時はfalseになるように後で設定します。

まず新規作成の設定です。今までは「ファイル」の「新規作成」を選択すると、有無を言わさず新規作成の作業を行いますが、その作業の前に今編集中のファイルが変更されているかを確認する作業を挿入します。
「新規作成」コマンドを実行するとFileNew1を呼び出し、そのFileNew1でメモ領域をクリアしたりしていましたが、FileNew1で行っていた作業をFileInit1(自分で作るイベント)にさせ、FileNew1では確認作業だけを行うように変更します。つまり

「新規作成」コマンド→FileNew1で変更の有無を確認→FileInit1でメモ領域をクリア

となるようにします。
フォーム上に置いたActionListをダブルクリックし、「分類」でファイルを選択した状態で「アクションの新規追加」を選択します。すると「アクション」の欄に「Action1」が追加されます。第5章でやったように、名前を「FileInit1」と変更するためにオブジェクトインスペクタの「Name」の項目を「FileInit1」に変えます。
オブジェクトツリーで、出来たFileInit1をダブルクリックするとUnit.pasの中に
procedure TForm1.FileInit1Execute(Sender: TObject);
が現れるので、そのbeginとendの間に、もともと
procedure TForm1.FileNew1Execute(Sender: TObject);
の中に書いてあった次の文を移動します。

Memo1.Clear;
FileName := 'untitled.txt';
StatusBar1.SimpleText := FileName;

更にその下に
isChange := false;

を追加します。

procedure TForm1.FileInit1Execute(Sender: TObject);の内容。タブはご自由に。

そして元々のprocedure TForm1.FileNew1Execute(Sender: TObject);の方には次のコードを入力します。次からは「beginとendの間に」と言う表現は省略します。

if( isChange = true ) then
case MessageDlg('ファイルが変更されています。保存してから新規作成しますか?', mtConfirmation, mbYesNoCancel, 0 ) of
mrYes:
begin
FileSave1.Execute;
FileInit1.Execute;
end;
mrNo: FileInit1.Execute;
mrCancel: ;
end
else
FileInit1.Execute;


新しいprocedure TForm1.FileNew1Execute(Sender: TObject);の内容。端っこ入りきらない…。

これで「新規作成」時、変更されているのにもかかわらず保存されていない場合は確認メッセージを出す事が出来ます。
確認処理と新規作成(初期化)作業を分離出来たので、ついでに実行と同時に初期化されるようにします。今までは実行時に「Memo1」という文字列がありましたが、これが実行時に消されます。
オブジェクトインスペクタでForm1を選択し、イベントタブの中のOnCreateを「FileInit1Execute」に設定します。

続いて「開く」の時の処理を設定します。これは「新規作成」の時と操作は似ていますがちょっと違います。「新規作成」の時はFileNew1からFileInit1という自分で作ったイベントを呼び出しましたが、現在「開く」コマンドから呼び出されるようになっているFileOpen1イベントはコード入力なしでファイルを開く操作をやってくれているので、この機能が実行される前に確認作業をしたいのです。従って、自分で確認作業をするイベント(FileCanOpen1と命名します)を挿入し、次のようにします。

「開く」コマンド→FileCanOpen1で変更の有無を確認→FileOpen1でファイルを開く

となるようにします。 先程と同様、フォーム上に置いたActionListをダブルクリックし、「分類」でファイルを選択した状態で「アクションの新規追加」を選択します。すると「アクション」の欄に「Action1」が追加されますので、オブジェクトインスペクタの「Name」の項目を「FileCanOpen1」に変えます。
オブジェクトツリーで、出来たFileCanOpen1をダブルクリックするとUnit.pasの中に
procedure TForm1.FileCanOpen1Execute(Sender: TObject);
が現れるので、その中に

if( isChange = true ) then
case MessageDlg('ファイルが変更されています。保存してから開きますか?', mtConfirmation, mbYesNoCancel, 0 ) of
mrYes:
begin
FileSave1.Execute;
FileOpen1.Execute;
end;
mrNo: FileOpen1.Execute;
mrCancel: ;
end
else
FileOpen1.Execute;

と入力します。


procedure TForm1.FileCanOpen1Execute(Sender: TObject);の内容

そのまま、そのウインドウの中からprocedure TForm1.FileOpen1Accept(Sender: TObject);の部分を探して、最後に

isChange := false;

を追記します。



続いて、「開く」コマンドが押された時、直接FileOpen1を呼び出していたのを、FileCanOpen1を呼び出すように変更します。
オブジェクトインスペクタでN1を選択するか、またはオブジェクトツリーの「MainMenu1」「ファイル(&F)」以下の「開く(&O)」を選択し、オブジェクトインスペクタのイベントタブにある「Action」の欄を「FileOpen1」から「FileCanOpen1」に変更します。すると名前まで「FileOpen1」に変わってしまうので、プロパティタブにある「Caption」を再び「開く(&O)」に戻します。

最後に、終了時の処理を設定します。「終了」コマンドが押された時のほかに、ウインドウ右上の「×」をクリックした時も終了してしまうので、確認操作をするには「終了」コマンドについての記述のみを操作するだけでは十分ではありません。
つまり「フォームが閉じる(終了コマンドと×のクリック、双方に共通する)」時にどんな操作が行われるかを考えなければなりません。
結論を言ってしまうとForm1のOnCloseQueryです。オブジェクトインスペクタまたはオブジェクトツリーからForm1を選択し、オブジェクトインスペクタのイベントタブにある「OnCloseQuery」の欄の白い部分をダブルクリックします。Unit.pasの中に

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);

が現れるので、その中に

if( isChange = true ) then
case MessageDlg('ファイルが変更されています。保存して終了しますか?', mtConfirmation, mbYesNoCancel, 0 ) of
mrYes: FileSave1.Execute;
mrNo: ;
mrCancel: CanClose := false;
end;

と入力します。

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);の内容

一つ忘れてました。上書き保存・名前を付けて保存する時に、ファイルが変更されているかを示すisChangeをfalseに設定しないといけません。
Unit.pasウインドウの中で今までと同様に
procedure TForm1.FileSave1Execute(Sender: TObject);
procedure TForm1.FileSaveAs1Accept(Sender: TObject);
を探し出し、それぞれ次の場所に
isChange := false;
を追加します。それぞれ次のようになります。FileSave1の方はelseの下にbegin、isChange := false;の下にend;を付け加えてください。


procedure TForm1.FileSave1Execute(Sender: TObject);の内容


procedure TForm1.FileSaveAs1Accept(Sender: TObject);の内容

これで一通り、ファイル操作に関してのイベントを設定しました。次はそろそろ最終回にしようと思っています。次回はやり残した部分と、カスタマイズの仕方を予定しています。


BACK
HOME