在我的主表单中,我有一个按钮,可以打开一个模态
问题是,当以模态方式打开
为了重现添加3个表单到项目中添加一个
Form2
(该表单可能会打开其他模态形式)。在打开Form2
之前,我设置了一个计时器,该计时器将以编程方式关闭所有活动的模态表单(Form2.Close
),并打开一个新的模态Form3
。问题是,当以模态方式打开
Form3
时,Form2
仍然保持(可见),只有当我通过单击X
关闭Form3
时,Form2
才会关闭。为了重现添加3个表单到项目中添加一个
TButton
,并在Form1
(主表单)上放置一个TTimer
。unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
uses Unit2, Unit3;
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Enabled := False;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Timer1.Enabled := True;
with TForm2.Create(Application) do
try
ShowModal;
finally
Free;
end;
end;
procedure CloseActiveModalForms;
var
I: Integer;
F: TCustomForm;
L: TList; // list of modal forms
begin
L := TList.Create;
try
for I := 0 to Screen.CustomFormCount - 1 do
begin
F := Screen.CustomForms[I];
if (fsModal in F.FormState) then
L.Add(F);
end;
for I := 0 to L.Count - 1 do
TCustomForm(L.Items[I]).Close; // this sets ModalResult := mrCancel
finally
L.Free;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
CloseActiveModalForms; // this should close TForm2 but it does not.
with TForm3.Create(Application) do // create new Modal TForm3
try
ShowModal;
finally
Free;
end;
end;
end.
为什么Form2
没有关闭?为什么在我调用CloseActiveModalForms
后,Form2
的模态循环没有退出?
Form2
没有存在ShowModal
的方法?模态循环检查ModalResult <> 0
,而调用Close
会设置ModalResult := mrCancel
。即使我在调用CloseActiveModalForms
之后调用Application.ProcessMessages
,循环也不会退出。我无法弄清楚原因。 - zigTimer1Timer
实际上是在本地模态消息循环中处理的。因此,使用PostMessage
延迟调用显示Form3
是可行的 - 这样可以让Form2
的本地消息循环退出,并关闭模态窗体。 - zigClose
调用之后,您还可以添加TCustomForm(L.Items[I]).Hide;
。模态窗体将被延迟释放,但如果在 Form3 中有检查它们的代码,则模态结果将被设置。不过,您的解决方案也是可以的。在此处没有风险,因为它们都是用户消息并具有相同的优先级,但不要忘记Close
也会发布一个消息 (CM_RELEASE
)。 - Sertac AkyuzClose
之前添加了Hide
。我非常确定除非您在关闭操作中显式指定一个caFree
(请参见TCustomForm.CloseModal
),否则默认情况下Close
不会调用Release
。ShowModal;...finally Free;
是释放模态窗体。 - zig