2

我想在创建 Tform2 时向用户显示一条消息。我使用此代码,但效果不佳。

procedure TForm1.Button1Click(Sender: TObject);
var
   a:TForm2;
begin

if a=nil then
 begin
    a := TForm2.Create(Self);
    a.Show;
 end
 else
 begin
    showmessage('TForm2 is created');
 end;

end;
4

2 回答 2

10

那是因为您声明a为局部变量。每次您输入TForm1.Button1Click此变量时,它都会是全新的且未初始化,即使可能仍然存在 Form2。这意味着对 nil 的检查甚至不起作用。

您应该:

  • 创建一个全局变量a(就像您第一次创建表单时获得的 Form2 全局变量)
  • aForm1 的声明(你的主窗体?)或其他类的数据模块作为整个程序的一部分。
  • 根本不要使用变量,但要检查Screen.Forms那里是否有 Form2。

[编辑]

像这样:

var
  i: Integer;
begin
  // Check
  for i := 0 to Screen.FormCount - 1 do
  begin
    // Could use the 'is' operator too, but this checks the exact class instead
    // of descendants as well. And opposed to ClassNameIs, it will force you
    // to change the name here too if you decide to rename TForm2 to a more
    // useful name.
    if Screen.Forms[i].ClassType = TForm2 then
    begin
      ShowMessage('Form2 already exists');
      Exit;
    end;
  end;

  // Create and show.
  TForm2.Create(Self).Show;
end;
于 2011-01-23T09:21:12.930 回答
0

解决问题的最简单方法是使用全局变量而不是局部变量,或者使变量成为类中的字段(实例变量)。

TForm2 类型的全局变量自动初始化为 nil,但正如您在上面发现的那样,位于称为“堆栈”的东西上的局部变量不是。

您应该阅读并了解局部和全局变量范围,以及堆栈和堆是什么。这些是适用于几乎所有未完全“托管”的编程语言的一般概念。换句话说,您必须在 C 和 C++ 以及 Pascal 中考虑这一点。

这样的事情(未初始化的局部变量和访问冲突)是某些语言(C# 和 java)在某种程度上保护你免受的事情。

于 2011-01-24T13:15:20.750 回答