procedure TForm2.FormShow(Sender: TObject);
begin
Close;
end;
としてもそのフォームを閉じることはできません。これはTCustomForm.Closeの実装がprocedure TCustomForm.Close;
var
CloseAction: TCloseAction;
begin
if fsModal in FFormState then
ModalResult := mrCancel
else
...
(Delphi 2007のForms.pasの5589行目付近より)とモーダルなフォームではModalResultをmrCancelに設定するだけで、一方TCustomForm.ShowModalは
function TCustomForm.ShowModal: Integer;
...
try
Show;
try
SendMessage(Handle, CM_ACTIVATE, 0, 0);
ModalResult := 0;
repeat
Application.HandleMessage;
if Application.Terminated then ModalResult := mrCancel else
if ModalResult <> 0 then CloseModal;
until ModalResult <> 0;
Result := ModalResult;
SendMessage(Handle, CM_DEACTIVATE, 0, 0);
if GetActiveWindow <> Handle then ActiveWindow := 0;
finally
Hide;
end;
...
end;
(Delphi 2007のForms.pasの5816行目付近より)となっており、Showの内部でCloseを呼び出してModalResultをmrCancel(など0以外の値)に変更しても、Showから戻ってきてから0に戻されてしまい、"
ModalResult <> 0
"という終了条件を満たさないためです。これを回避するには例えばTTimerを使う方法も考えられますが、お手軽な解決として
procedure TForm2.FormShow(Sender: TObject);
begin
PostMessage(Handle,WM_CLOSE,0,0);
end;
と自分(モーダルなフォーム)にWM_CLOSEメッセージをpost(sendではない)するという方法があります。PostされたWM_CLOSEメッセージはメッセージキューの最後に追加され、repeat-untilループの内部のApplication.HandleMessageでディスパッチされてTCustomForm.WMCloseから最終的にCloseが呼び出されることでModalResultが0以外の値になり、終了条件を満たしてフォームが閉じる、という仕組みです。
0 件のコメント:
コメントを投稿