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 のチェックも機能しません。

次のいずれかを行う必要があります。

  • グローバルを作成します (最初にフォームを作成したときに得られるForm2aグローバルのように)
  • Form1 a(メインフォームですか?)またはプログラム全体に存在する他のクラスのデータモジュールの宣言の一部を作成します。
  • 変数をまったく使用しないでください。ただし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 に初期化されますが、上記でわかったように、「スタック」と呼ばれるものにあるローカル変数はそうではありません。

ローカル変数とグローバル変数のスコープ、およびスタックとヒープとは何かについて読んで学ぶ必要があります。これらは、完全に「管理」されていないほとんどすべてのプログラミング言語に適用される一般的な概念です。つまり、Pascal だけでなく、C や C++ でもこれを考える必要があります。

このようなこと (初期化されていないローカル変数、およびアクセス違反) は、一部の言語 (C# および Java) によってある程度保護されています。

于 2011-01-24T13:15:20.750 に答える