コラム / バイナリエディタ / 26



そうそう、前回の緑色の疑問符 ですが、
実行してみたら、

img6.png

でした。緑じゃNEEEEEEEEEEEEEEEEEET
それじゃ早速
ファイル>開く をクリックして
procedure TForm1.Open1Click(Sender: TObject);
       (略)
begin
   if not OpenDialog1.Execute then
   begin
       exit;
   end;
      ・
   ・
   ・
     (略)
end;

を、

procedure TForm1.Open1Click(Sender: TObject);
  (略)
begin
   if Memo1.Modified then begin
       Case MessageDlg('( ^ω^)変更されてるけど保存するお?',
       mtConfirmation,mbYesNoCancel,0) of
            mrYes:SaveAs1Click(Sender);
            mrCancel:Exit;
       end;
   end;

   if not OpenDialog1.Execute then
   begin
       exit;
   end;
   Memo1.Modified:=False;
      ・
   ・
   ・
     (略)
end;
としましょう。
ぶっちゃけ、前回と意味は変わってません。
ただ、
値:begin
   命令
end;
の、begin,end;を削除しました。
Caseもifやらと同じで、命令が一つならくくらなくて良いのです。
また、mrNoneの時の分岐を削除しました。
Case文では、出てきた結果の処理が、
全部記述されてなくてもかまいません。
結果がかかれてなければスルーします。
それと、Memo1.Modified:=False;の位置が変わりました。
OpenDialogがTrueを返すまでは、
開く処理が行われるかはっきりしないので、
Modifiedプロパティーをいじるわけにはいきません。
開けなかったら初期化されないから、もとのまま、
変更有り を保持しないといけないですから。
さて、あとはフォームが閉じられるときです。
これはどこに記述すればいいのでしょうか?
答えは、フォームのイベントです。
フォームのイベントには、
onCloseとonCloseQueryがあります。
onCloseは閉じられる時なのでできませんが、
onCloseQueryは「閉じられようとしている時」で、
閉じさせない という指定が簡単にできます。
(onCloseでもできるのかもしれないけどよく知らないっす
久々のキャプチャ画像ですよん!
さて、フォームは、memoとメインメニューで埋められていて、
フォームの肌が覗いているところがありません。
そういう時は、オブジェクトツリーから直接選択しましょう。

img7.png

そうすればオブジェクトインスペクタがform1のものになるので、
イベントタブを開いて、
onCloseQueryイベントをダブルクリック。

img8.png

さぁて 出てきたコードを編集だ
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin

end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
   if Memo1.Modified then begin
       Case MessageDlg('( ^ω^)変更されてるけど保存するお?',
       mtConfirmation,mbYesNoCancel,0) of
            mrYes:SaveAs1Click(Sender);
            mrCancel:CanClose:=False;
       end;
   end;
end;
としよう。
Cancelの時の処理が変わり、modified:=Falseがなくなっています。
まぁ、後者は当然ですね。
フォームを閉じようとしているだけなので、
閉じても閉じなくても、 変更アリ は 変わってはいけません。
(実はまだ少し嘘がありますが それはもうちょい後で
さて、Cancelの方は、
CanClose:=False;となっています。
CanCloseってなんでしょうか?
英語がわかる人は勘付いたと思いますが、
procedureの行を見てください。実は、引数です。
この引数、var が付いていますね。
varが付いている引数は、
渡されるだけじゃなく、関数の中で値を変えると、
呼び出し側で渡した引数の値も変わるのです。
onCloseQueryでは、CanCloseの値をFalseにすると、
フォームが閉じられなくなります。
CanClose は 閉じられる っていう意味ですから、
まぁ気付いた人は気づいたかと思います。
さて、これで、警告の実装が終わりました。
しかし、まだ足りません。
保存したときに、modifiedをFalseにしないといけないんです。
そうしないと、いくら上書き保存しても、
閉じようとすると警告が出てきます。
名前をつけて保存 でも対応しなくてはなりません。
いやぁ、あの時手続きを共通化しておいて良かったです。
SaveBinText手続きを編集します。
procedure SaveBinText(SaveTo:String);
  (略)
begin
 (略)
   FS.Free;
end;
これを、
procedure SaveBinText(SaveTo:String);
  (略)
begin
 (略)
   FS.Free;

   Form1.Memo1.Modified:=False;
end;
としてください。
SaveBinTextは最上位階層なので、
Memo1を見るときは Form1.をつけるのを忘れずに。
これで、保存警告システムも完成です!
ひとまず安心して使ってください〜〜〜 フォーーー