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 件のコメント:
コメントを投稿