打开并关闭vcl表单

hs2*_*s2d 5 forms delphi

现在我有2个表格.在Form1上,我打开Form2,如下所示:

procedure TForm1.Action1Execute(Sender: TObject);
var
  Form2: TForm2;
begin
  Form2 := TForm2.Create(Form2);
  Form2.ShowModal;
  Form2.Free;
end;
Run Code Online (Sandbox Code Playgroud)

现在我想用一个按钮关闭Form2.所以我试过了

procedure TForm2.cancelBtnClick(Sender: TObject);
begin
  Form2.Close;
end;`
Run Code Online (Sandbox Code Playgroud)

但是,当我单击该按钮时,这只会给我访问冲突错误.我做错了什么?

And*_*and 17

正常的方法是这样做

procedure TForm1.Action1Execute(Sender: TObject);
begin
  with TForm2.Create(nil) do
    try
      ShowModal;
    finally
      Free;
    end;
end;
Run Code Online (Sandbox Code Playgroud)

并且,如果TForm2包含一个OK按钮,则应该在设计时将ModalResult属性设置为mrOK.使用对象检查器进行设置.您可能还想设置DefaultTrue.现在,您可以通过按键盘上的Enter键"单击"确定按钮!

此外,如果对话框中有"取消"按钮,则应ModalResult设置为mrCancelCancel设置为True.现在,您可以通过按键盘上的Escape键"点击"取消按钮!

带有ModalResult值的按钮将自动关闭模式对话框.

  • @Andreas:当所有者传递给构造函数时,所有者应该负责释放组件。如果省略了所有者,则构造函数和析构函数的执行会更快,因为所有者不需要维护组件的所有权。 (2认同)

Dav*_*nan 6

由于表单以模态显示,因此正确的解决方案是ModalResult := mrCancel在按钮单击处理程序中设置.快捷方式是ModalResult将按钮的属性设置为mrCancel,然后您甚至不需要事件处理程序.


请注意,您的表单创建不正确.您将未分配的变量Form2作为Owner参数传递给构造函数.我希望这是访问冲突的原因.

你应该传递另一个表格,Application或者nil,例如.实际上在这种情况下你也可以传递nil,以便代码应该是:

Form2 := TForm2.Create(nil);
try
  Form2.ShowModal;
finally
  Form2.Free;
end;
Run Code Online (Sandbox Code Playgroud)

如果您通过所有者,则在销毁所有者时将销毁该表单.由于您自己正在销毁它,因此您无需通过所有者.

也就是说,设置所有者有时很有用,例如,如果您使用其中一个Postion属性值根据所有者的位置设置表单的位置.如果是这样,那么我建议传入Self这个实例,这是一个TForm1对象引用.