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


tomomi  2006-01-17 00:35:55  No: 19679

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-17 01:40:20  No: 19680

何をしたいのかよくわかりませんが、普通の方法でやるなら、
単に、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-17 02:17:34  No: 19681

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

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


tomomi  2006-01-17 22:38:23  No: 19682

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

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

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


わからんちん  2006-01-18 02:39:43  No: 19683

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


tomomi  2006-01-18 23:10:34  No: 19684

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


tomomi  2006-01-19 01:12:09  No: 19685

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


横ヤリ  2006-01-19 01:51:03  No: 19686

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

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


tomomi  2006-01-19 06:29:18  No: 19687

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

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

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

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


わからんちん  2006-01-19 07:03:18  No: 19688

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

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

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

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


-toyay  2006-01-19 07:13:36  No: 19689

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

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

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


わからんちん  2006-01-20 12:07:33  No: 19690

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.


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加