.Createでnull参照になってしまう件について


tomomi  2006-01-16 15:35:55  No: 19679  IP: 192.*.*.*

Delphi2005.NETです。

TFormを継承して作成したTtestクラスのインスタンスを作成しようとすると
null参照エラーとなってしまいます。
回避方法がわかりません。

【メインフォーム.pas】
procedure TfrmMainform.XXXX(Sender:TObject);
var
  dlg:Ttest;
begin
  dlg := Ttest.Create(Application); ←ここでエラー
end;

【testフォーム.pas】
Ttest = class(TForm)
  :
 //コンストラクタの作成はしていない
end;

編集 削除
わからんちん  2006-01-16 16:40:20  No: 19680  IP: 192.*.*.*

何をしたいのかよくわかりませんが、普通の方法でやるなら、
単に、Show で済むでしょうから、「動的に作り出すには・・」と言う観点から
上げてみます。

// 新しいフォームを動的に作り出す。
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

type
  TForm2 = class(TCustomForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;
  Form2: TForm2;

implementation

{$R *.DFM}


procedure TForm1.Button1Click(Sender: TObject);
begin
  if Form2 <> nil then Exit;

  Form2 := TForm2.CreateNew(self);
  with  Form2 do
  begin
    Top := 100;
    Left := 100;
    Show;
    Button1 :=  TButton.Create(Form2);
    with  Button1 do
    begin
      Parent :=  Form2;
      Top := 20;
      Caption := 'My Botton';
      OnClick := Button1Click;
    end;
  end;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  Showmessage('OK');
end;

end.

編集 削除
わからんちん  2006-01-16 17:17:34  No: 19681  IP: 192.*.*.*

こっちのほうがいいかな・・・。

  if Form2 <> nil then begin Form2.Show; Exit; End;

編集 削除
tomomi  2006-01-17 13:38:23  No: 19682  IP: 192.*.*.*

CreateNewでフォームを表示させることはできました。
わからんちんさん、ありがとうございました!
フォーム上のコンポーネントの設定をFormCreate内で
行いたいのですが、その場合は

 dlg := Ttest.CreateNew(self);
 dlg.FormCreate(Sender);
 dlg.show;

とすればよいのですよね?

編集 削除
わからんちん  2006-01-17 17:39:43  No: 19683  IP: 192.*.*.*

例示では、ボタンでメイクした部分を単に FormCreate に置き換えるだけで
できます。

編集 削除
tomomi  2006-01-18 14:10:34  No: 19684  IP: 192.*.*.*

dlgをモーダル表示させたいのですが、
dlg.showModal
とするとnull参照エラーとなってしまいました。
モーダル表示させるにはどうしたらよいのでしょう。

編集 削除
tomomi  2006-01-18 16:12:09  No: 19685  IP: 192.*.*.*

いまさらですが、フォームの動的生成をやめて
dfmに依存する形にしたいです。
理由は、フォーム上のコンポーネント数が多いからです。
その場合は、どうしたらよいのでしょう。

編集 削除
横ヤリ  2006-01-18 16:51:03  No: 19686  IP: 192.*.*.*

> dfmに依存する形にしたいです。
> 理由は、フォーム上のコンポーネント数が多いからです。
> その場合は、どうしたらよいのでしょう。

質問の意味わからん。
フォームの新規作成で設計するのと違うわけ?

編集 削除
tomomi  2006-01-18 21:29:18  No: 19687  IP: 192.*.*.*

すみません、なぜそうしたいと思ったかを説明していませんでした。
CreateNewでフォームの表示までできるようになったのですが、
実際表示できたのはコンポーネントが全く表示されていない状態の
フォームのみでした。

で、まずコンポーネントが表示されていない原因をFormCreate内で発生していたエラーだと思いました。
実際、
Button1.Caption := 'My Botton';
とする前に、Button1 :=  TButton.Create(Form2);
をやっていなかったので、その部分は修正してエラーはでなくなったのですが、
そのあと空の画面が表示されたので、?となったのです。

次に、いまさらながらですがCreateNewについて調べてみました。
ヘルプに「ほとんどのフォームはコントロールが .DFM ファイルから作成されることを前提に記述されるので,予期できない結果が起こることもあります。」とあったので、CreateNewを使ったこと原因なのかと思い、CreateNew以外でフォーム作成する方法をおしえていただきたかったのです。

基本的に何をしたいかと言いますと、
・メインフォーム上にTTestクラスのダイアログをモーダル表示させたい
・TTestクラスのダイアログ上のいくつかのコンポーネントの初期設定はTTest.FormCreate内で行いたい
・Delphi5をDelphi2005にコンバージョンしているため、既存ロジックの修正は最低限にしたい
(最初にかいておくべきでした、申し訳ありません)

編集 削除
わからんちん  2006-01-18 22:03:18  No: 19688  IP: 192.*.*.*

うーむ、普通の方法で、最初からFormCreateの中で、
Form2.ShowModal; をやると実行時エラーになりますね。

サンプルの該当部分を同様にしてみると
問題なく表示できるようなんですが・・・。

どうして、最初からコンポの多いモーダル・フォームが必要なのか・・・が
大きな疑問ですが、簡単には、サンプルを改造するのが手っ取り早いかと・・。

# 上記問題については、解答を持ち合わせていません。

編集 削除
-toyay  2006-01-18 22:13:36  No: 19689  IP: 192.*.*.*

あれ、長時間開いたままにしておいたら、追加記入があった・・・。
と、それはともかく。

>そのあと空の画面が表示されたので、?となったのです。
      Parent :=  Form2;
をちゃんとやってないと想像しますが・・・。
とりあえず。移植はひとまずおいて、サンプルを一度実行して、
理解したその上で、移植再開してみてください。

基本的な部分は、おそらくDelphi のバージョンに依存しないと思いますが・・。

編集 削除
わからんちん  2006-01-20 03:07:33  No: 19690  IP: 192.*.*.*

FormCreate の中ではできないようですね。
プロジェクト・ファイルのソースを以下のようすればできるようです。

// 定義済みダイアログをメインフォーム起動前に表示させる
program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.RES}
var  frm2: TForm2; //←追加
begin
  Application.Initialize;
    frm2 := TForm2.Create(Application.MainForm); //←追加
    frm2.ShowModal ; //←追加
  Application.CreateForm(TForm1, Form1);
//  Application.CreateForm(TForm2, Form2); //←削除
  Application.Run;
end.

編集 削除