delphi表单创建

delphi表单创建,delphi,Delphi,我已经在Delphi7中创建了一个应用程序。我的主窗体调用子窗体的执行过程。执行过程创建子窗体的对象并向用户显示子窗体。我已从自动创建中删除子窗体。现在,我在子窗体上添加了一个编辑框,并尝试在执行过程中创建的子窗体之后设置文本。但在这种情况下,我得到了访问冲突错误。如果我使用subform.editbox设置文本,那么它不会给出任何错误。当表单不是自动创建时,是否总是强制使用具有表单引用的组件?谢谢你的帮助 function TSubForm.execute(temp:String); begi

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

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

形式与其他对象没有太大区别。您需要创建它(使用
Application.CreateForm(..)
或手动使用
Form2:=TForm2.create(..)
)。除非创建了它,否则您当然会得到一个AccessViolation,因为Form2=nil

编辑

A.您没有指定声明
frmSubForm
的位置和方式。它是否意味着是
TSubForm
form的一个单独实例

看起来您运行了函数TSubForm.execute(temp:String)来自尚未创建的表单。也许这应该是一个类函数


C.您可以有效地访问
Self.edit1
您的问题在哪里听起来像是想访问
frmSubForm.edit1

以下是使用非自动创建表单(TForm2)的典型代码:

如果要将Form2显示为非模式(
show
而不是
showmodel
),则应在
OnClose
处理程序中将其关闭操作设置为
caFree

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;

您应该像这样访问文本框文本:

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

另外,在使用完子表单后,请在子表单上拨打免费电话。

我不认为我会这样做,但这是可行的:

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的地方。

您所做的是危险的。方法可以隐式访问对象的所有字段,即使它可能尚未创建。尝试将其改为类方法:

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;

(顺便说一句:您的函数没有返回类型。)

我已经使用Tform2.create(..)在执行过程的开头创建了表单。之后,我使用editbox来设置文本。您是否将其赋值为
Form2:=TForm2.Create(..)
?1.frmSubForm是在同一单元中声明的TSubForm的实例。2.我只是通过在Mainform中添加子表单来调用execute函数。3.我想知道为什么自动创建和手动创建有区别。2是你的错误。您正在访问尚未创建的表单执行函数;)如果表单未创建,那么它是否强制使用表单引用?比如frmSubForm.edit1.text?如果我在自动创建中添加了该表单,那么就不需要像frmSubForm.edit1一样使用它。我们可以通过edit1.text直接分配它。但是为什么我们必须在手动创建中提供引用?如果此表单是自动创建的,您也需要调用frmSubForm.edit1。这没什么区别,我已经测试过了。如果我在自动创建中添加了子表单,并且没有使用TSubForm.create(self);如果只使用edt1.text,那么就不会有任何错误。我喜欢@dummzeuch的想法,所以我修改了答案,在表单中使用了一个类函数和一个局部变量。
class function TSubForm.execute(temp:String);
begin
  frm:= TSubForm.create(self);
  try
    frm.edit1.text:= temp;
    frm.ShowModal;
  finally
    frm.Free;
  end;
end;