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;
何をしたいのかよくわかりませんが、普通の方法でやるなら、
単に、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.
こっちのほうがいいかな・・・。
if Form2 <> nil then begin Form2.Show; Exit; End;
CreateNewでフォームを表示させることはできました。
わからんちんさん、ありがとうございました!
フォーム上のコンポーネントの設定をFormCreate内で
行いたいのですが、その場合は
dlg := Ttest.CreateNew(self);
dlg.FormCreate(Sender);
dlg.show;
とすればよいのですよね?
例示では、ボタンでメイクした部分を単に FormCreate に置き換えるだけで
できます。
dlgをモーダル表示させたいのですが、
dlg.showModal
とするとnull参照エラーとなってしまいました。
モーダル表示させるにはどうしたらよいのでしょう。
いまさらですが、フォームの動的生成をやめて
dfmに依存する形にしたいです。
理由は、フォーム上のコンポーネント数が多いからです。
その場合は、どうしたらよいのでしょう。
> dfmに依存する形にしたいです。
> 理由は、フォーム上のコンポーネント数が多いからです。
> その場合は、どうしたらよいのでしょう。
質問の意味わからん。
フォームの新規作成で設計するのと違うわけ?
すみません、なぜそうしたいと思ったかを説明していませんでした。
CreateNewでフォームの表示までできるようになったのですが、
実際表示できたのはコンポーネントが全く表示されていない状態の
フォームのみでした。
で、まずコンポーネントが表示されていない原因をFormCreate内で発生していたエラーだと思いました。
実際、
Button1.Caption := 'My Botton';
とする前に、Button1 := TButton.Create(Form2);
をやっていなかったので、その部分は修正してエラーはでなくなったのですが、
そのあと空の画面が表示されたので、?となったのです。
次に、いまさらながらですがCreateNewについて調べてみました。
ヘルプに「ほとんどのフォームはコントロールが .DFM ファイルから作成されることを前提に記述されるので,予期できない結果が起こることもあります。」とあったので、CreateNewを使ったこと原因なのかと思い、CreateNew以外でフォーム作成する方法をおしえていただきたかったのです。
基本的に何をしたいかと言いますと、
・メインフォーム上にTTestクラスのダイアログをモーダル表示させたい
・TTestクラスのダイアログ上のいくつかのコンポーネントの初期設定はTTest.FormCreate内で行いたい
・Delphi5をDelphi2005にコンバージョンしているため、既存ロジックの修正は最低限にしたい
(最初にかいておくべきでした、申し訳ありません)
うーむ、普通の方法で、最初からFormCreateの中で、
Form2.ShowModal; をやると実行時エラーになりますね。
サンプルの該当部分を同様にしてみると
問題なく表示できるようなんですが・・・。
どうして、最初からコンポの多いモーダル・フォームが必要なのか・・・が
大きな疑問ですが、簡単には、サンプルを改造するのが手っ取り早いかと・・。
# 上記問題については、解答を持ち合わせていません。
あれ、長時間開いたままにしておいたら、追加記入があった・・・。
と、それはともかく。
>そのあと空の画面が表示されたので、?となったのです。
Parent := Form2;
をちゃんとやってないと想像しますが・・・。
とりあえず。移植はひとまずおいて、サンプルを一度実行して、
理解したその上で、移植再開してみてください。
基本的な部分は、おそらくDelphi のバージョンに依存しないと思いますが・・。
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.
ツイート | ![]() |