2011-12-29 90 views
-1

我在delphi 7中创建了一个应用程序。我的主窗体调用子窗体的执行过程。执行过程创建子窗体的对象并将子窗体显示给用户。我已经从自动创建中删除了子窗体。现在,我在子窗体上添加了一个编辑框,并试图在执行过程中创建子窗体后设置文本。但在这种情况下,我得到访问冲突错误。如果我使用subform.editbox设置文本,那么它不会给出任何错误。未自动创建表单时,是否总是使用具有表单参考的组件?感谢帮助。delphi表单创建

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

显示你的代码,请! – evilone 2011-12-29 09:41:56

+0

如果表单没有被自动创建,那么它的使用形式参照的授权?像frmSubForm.edit1.text? – Nalu 2011-12-29 10:06:35

回答

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(..))。除非它被创建,否则你将获得一个AccessViolation,Form2 = nil。

编辑

A.你没有指定的地点和frmSubForm的声明方式。它是否意味着是一个单独的TSubForm表单实例? B.您看起来像是从尚未创建的表格中运行function TSubForm.execute(temp:String);。也许这应该是一个类功能。

C.你有效地访问Self.edit1凡在你的问题是你听起来像你想访问frmSubForm.edit1

+0

我使用Tform2.create(..)创建了执行过程的开始窗体。之后,我用编辑框设置文本。 – Nalu 2011-12-29 09:48:15

+0

你有没有为它分配'Form2:= TForm2.Create(..)'? – Kromster 2011-12-29 09:58:52

+0

是的,就像你上面提到的一样。 – Nalu 2011-12-29 10:00:33

1

下面是使用非自动创建形式的典型代码(TForm2):

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; 

如果您要显示窗体2作为非模态(Show而不是ShowModal),你应该设置其caFree关闭行动OnClose处理:

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 2011-12-29 10:26:28

+1

如果这个表单是自动创建的,您也需要调用frmSubForm.edit1。这没有什么区别。 – evilone 2011-12-29 11:00:12

+0

我已经测试过。如果我在自动创建中添加子窗体并且不使用TSubForm.create(self);那么只使用edt1.text时不会有任何错误。 – Nalu 2011-12-29 11:45:30

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. 

然后用它从第一种形式,像这样:

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

返回一个ShowModal的状态的确没有伤害,你永远不知道你什么时候需要它。

您可能不应直接访问其他对象(窗体或其他)的属性;如果TEdit将来成为TLabel,则只需更改一次frmSubForm,而不是访问frmSubForm.Edit.Text的地方,请使用父对象的propery。

+0

我喜欢@dummzeuch的想法,所以我修改了我的答案,为表单使用类函数和局部变量。 – TDC 2011-12-29 15:23:30