2011-12-29 8 views
-1

私はdelphi 7でアプリケーションを作成しました。メインフォームはサブフォームの実行プロシージャを呼び出します。 Executeプロシージャは、サブフォームのオブジェクトを作成し、そのサブフォームをユーザーに表示します。サブフォームを自動作成から削除しました。今私はサブフォームに1つの編集ボックスを追加し、実行プロシージャで作成されたサブフォームの後にテキストを設定しようとしました。しかし、この場合、私はアクセス違反エラーが発生しています。私がsubform.editboxを使ってテキストを設定すると、エラーは発生しません。フォームが自動作成されていない場合、フォーム参照を使用してコンポーネントを使用するのはいつも万能ですか?手伝ってくれてありがとう。デルファイフォームの作成

function TSubForm.execute(temp:String); 
begin 
    frmSubForm:= TSubForm.create(self); 
    edit1.text:= temp; 
    frmSubForm.ShowModal; 
end; 
+1

はあなたのコードを表示してください! – evilone

+0

フォームが自動作成されていない場合、そのフォームの参照を使用するマンゴトリーですか? frmSubForm.edit1.textのような? – Nalu

答えて

2

あなたがしていることは危険です。メソッドがまだ作成されていなくても、メソッドはオブジェクトのすべてのフィールドに暗黙的にアクセスできます。代わりにクラスメソッドを作ってみるん:

class function TSubForm.execute(temp:String); 
begin 
    frmSubForm:= TSubForm.create(self); 
    edit1.text:= temp; 
    frmSubForm.ShowModal; 
end; 

(また、クラス宣言でそれを適応させる) それは、クラスの変数ではないので、その変更した後、コンパイラはもはやあなたがEDIT1にアクセスできるようになるのではなくそのクラスのインスタンスの

class function TSubForm.execute(temp:String); 
begin 
    frmSubForm:= TSubForm.create(self); 
    frmSubForm.edit1.text:= temp; 
    frmSubForm.ShowModal; 
end; 

をしかし、注意してください:だから、正しいコードは次のようになりますあなたのfrmSubForm変数はメソッド内で宣言されていないので、それはおそらく世界です。フォームをどこから解放しますか?これはきれいになります:

class function TSubForm.execute(temp:String); 
begin 
    frm:= TSubForm.create(self); 
    try 
    frm.edit1.text:= temp; 
    frm.ShowModal; 
    finally 
    frm.Free; 
    end; 
end; 

(ところで:あなたの関数は、戻り値の型を持っていません。)

3

フォームは他のオブジェクトとあまり変わりません。作成する必要があります(Application.CreateForm(..)または手動でForm2 := TForm2.Create(..))。それが作成されていない限り、もちろんForm2 = nilとしてAccessViolationを取得します。

EDIT

A.あなたはどこに指定していないとfrmSubFormがどのように宣言されています。それはTSubFormフォームの別のインスタンスであることを意味していますか?

B.まだfunction TSubForm.execute(temp:String);をまだ作成されていないフォームから実行したようです。おそらく、これはクラス関数でなければなりません。

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

begin 
    Form:= TForm2.Create(Application); 
    try 
    Form.Edit1.Text:= 'Hello'; 
    Form.ShowModal; 
    finally 
    Form.Free; 
    end; 
end; 

あなたの場合:ご質問にありますどこ

C.あなたは効果的にあなたがここ

+0

Tform2.create(..)を使用して実行プロシージャの開始時にフォームを作成しました。その後、私はeditboxを使ってテキストを設定しています。 – Nalu

+0

これを 'Form2:= TForm2.Create(..)'に割り当てましたか? – Kromster

+0

上記と同じ方法ではい。 – Nalu

1

frmSubForm.edit1が非自動作成フォームを使用するための一般的なコード(TForm2)でアクセスしてみたかったような音Self.edit1にアクセスあなたはOnCloseハンドラ内caFreeにその近くにアクションを設定する必要があります(代わりにShowModalShow)非モーダルとしてのForm2を表示したい:

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
    Action:= caFree; 
end; 

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

begin 
    Form:= TForm2.Create(Application); 
    Form.Edit1.Text:= 'Hello'; 
    Form.Show; 
end; 
1

あなたはこのようなあなたのテキストボックスのテキストをアクセスもする必要があります。また

function TSubForm.execute(temp:String); 
begin 
    frmSubForm:= TSubForm.create(self); 
    frmSubForm.edit1.text:= temp; 
    frmSubForm.ShowModal; 
end; 

、あなたはそれで行われた後、サブフォーム上の自由を呼び出します。

+0

自動作成でそのフォームを追加した場合、frmSubForm.edit1のように使う必要はありません。 edit1.textで直接割り当てることができます。しかし、なぜマニュアル作成で参照を与える必要がありますか? – Nalu

+1

このフォームを自動作成する場合は、frmSubForm.edit1も呼び出す必要があります。それには違いはありません。 – evilone

+0

私はテストしました。私は自動作成でサブフォームを追加し、TSubForm.create(自己)を使用しないでください。 edt1.textだけを使用している間はエラーは発生しません。 – Nalu

1

私はそれをこのように行うだろうとは思わないが、これは動作します:

unit UfrmSubForm; 

interface 

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

type 
    TfrmSubForm = class(TForm) 
    edit1: TEdit; 
    private 
    procedure Set_EditText(const Value: String); 
    { Private declarations } 
    public 
    { Public declarations } 
    class function Execute(Temp: String): TModalResult; 
    property EditText: String write Set_EditText; 
    end; 


function SubFormExecute(Temp: String): TModalResult; 

implementation 

{$R *.dfm} 

{ TfrmSubForm } 

class function TfrmSubForm.Execute(Temp: String): TModalResult; 
var 
    frmSubForm: TfrmSubForm; 
begin 
    frmSubForm := TfrmSubForm.Create(Application); 
    try 
    frmSubForm.EditText := Temp; 
    Result := frmSubForm.ShowModal; 
    finally 
    frmSubForm.Free; 
    end; 
end; 

procedure TfrmSubForm.Set_EditText(const Value: String); 
begin 
    edit1.Text := Value; 
end; 

end. 

そして、そのような最初のフォームからそれを使用します。ShowModal DOEのステータスを返す

procedure TForm1.btnExecuteClick(Sender: TObject); 
begin 
    TfrmSubForm.Execute('Some Text'); 
end; 

あなたがそれを必要とするかもしれないことは決して分かりません。

他のオブジェクト(フォームなど)のプロパティに直接アクセスしないでください。 TEditが将来TLabelになる場合には、frmSubFormを一度だけ変更するだけで、frmSubForm.Edit.Textにアクセスする場所は変わらないように、親オブジェクトのプロパティを使用してください。

+0

@dummzeuchアイデアが好きなので、フォームのクラス関数とローカル変数を使用するように答えを変更しました。 – TDC

関連する問題