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