【问题标题】:Updating a child from a child not working [duplicate]从不工作的孩子更新孩子[重复]
【发布时间】:2014-01-24 18:26:43
【问题描述】:

Form 10 创建并显示 form11,form11 创建并显示 form12。然后 form12 尝试更新 form10 上的控件(成功)、form11 上的控件(访问冲突)和 form12 上的控件(成功)。为什么我在更新中间表单 form11 时遇到访问冲突。评论语句 30 和 31 不起作用,我想知道为什么。 30 正在更新中间表格。 31 是一个旁白,不相关,但它不起作用,我不确定它为什么会爆炸。

1: unit Unit10;
2:
3: interface
4:
5: uses
6: Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7: Dialogs, StdCtrls;
8:
9: type
10: TForm10 = class(TForm)
11: Button1: TButton;
12: procedure Button1Click(Sender: TObject);
13: private
14: { Private declarations }
15: public
16: { Public declarations }
17: end;
18:
19: var
20: Form10: TForm10;
21:
22: implementation
23: uses Unit11;
24:
25: {$R *.dfm}
26:
27: procedure TForm10.Button1Click(Sender: TObject);
28: var
29: fForm11 : TForm11;
30: begin
31: fForm11 := TForm11.Create(Application);
32: fForm11.show;
33: end;
34:
35: end. 

1: unit Unit11;
2:
3: interface
4:
5: uses
6: Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7: Dialogs, StdCtrls;
8:
9: type
10: TForm11 = class(TForm)
11: Button1: TButton;
12: procedure Button1Click(Sender: TObject);
13: private
14: { Private declarations }
15: public
16: { Public declarations }
17: end;
18:
19: var
20: Form11: TForm11;
21:
22: implementation
23: uses Unit12, Unit10;
24:
25: {$R *.dfm}
26:
27: procedure TForm11.Button1Click(Sender: TObject);
28: var
29: fForm12 : TForm12;
30: begin
31: form10.Button1.Caption := 'done';
32: fForm12 := TForm12.Create(Self);
33: fForm12.show;
34: end;
35:
36: end.

1: unit Unit12;
2:
3: interface
4:
5: uses
6: Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7: Dialogs, StdCtrls;
8:
9: type
10: TForm12 = class(TForm)
11: Button1: TButton;
12: procedure Button1Click(Sender: TObject);
13: private
14: { Private declarations }
15: public
16: { Public declarations }
17: end;
18:
19: var
20: Form12: TForm12;
21:
22: implementation
23: uses Unit11, Unit10;
24:
25: {$R *.dfm}
26:
27: procedure TForm12.Button1Click(Sender: TObject);
28: begin
29: Form10.Button1.Caption := 'Unit10';
30: //Form11.Button1.Caption := 'Unit11';   //get an access violation
31: //Form12.Button1.Caption := 'Unit12';   //get an access violation           
32: Button1.Caption := 'Unit12';            //this same as 31 without Form12 prefix
33: end;
34:
35: end.

【问题讨论】:

  • 我们很高兴您向新手提问,但我们希望您阅读答案并注意。

标签: delphi


【解决方案1】:

你需要更加注意你的变量名、声明和使用。

您发布的代码中有两个与Form11 相关的完全独立的变量。

第一个是由 IDE 自动添加的 global Form11(如果您不自动创建表单,则应将其删除,因为这是第一个存在的唯一原因地方),在Unit11.pasinterface部分声明:

type
 TForm11 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 end;

 var
    Form11: TForm11

第二个是一个名为fForm11本地 变量,您在按钮单击处理程序中在Unit10.pas 中声明:

procedure TForm10.Button1Click(Sender: TObject);
var
  fForm11 : TForm11;
begin

第二个是您分配给您创建的表单的实际实例的那个:

procedure TForm10.Button1Click(Sender: TObject);
var
  fForm11 : TForm11;
begin
  fForm11 := TForm11.Create(Application);   // Assigns to the *local* fForm11
  fForm11.show;                             // Shows this copy of the form
end;

您在Unit12 中使用的Unit12,您已将其注释掉并提到它会导致访问冲突是全局 Form11,这是唯一可见的这段代码:

procedure TForm12.Button1Click(Sender: TObject);
begin
  Form10.Button1.Caption := 'Unit10';
  //Form11.Button1.Caption := 'Unit11';   //get an access violation
  //Form12.Button1.Caption := 'Unit12';   //get an access violation           
  Button1.Caption := 'Unit12';            //this same as 31 without Form12 prefix
end;

问题是您从未创建过TForm11 的实例并将其分配给Form11;您创建并将其分配给 local fForm11,而这根本不在范围内。

解决方法应该很明确:删除局部变量,并将您在那里创建的表单分配给适当的变量。

然而,对您来说适当的解决方法是自动创建表单,因为您非常鲁莽地到处使用它们。如此糟糕地使用模块间依赖关系,您最终会一遍又一遍地遇到相同类型的问题,当您尝试访问它们时不会创建东西。

【讨论】:

  • 非常感谢您的帮助,您的指导帮助我解决了访问违规问题。
  • @OwenH 您可以通过接受 Ken 的回答并单击其左侧的复选标记来表示感谢。
猜你喜欢
  • 2018-12-09
  • 2021-07-21
  • 2018-01-25
  • 2014-02-14
  • 2020-05-08
  • 1970-01-01
  • 2019-01-21
  • 2018-11-24
  • 1970-01-01
相关资源
最近更新 更多