2014-01-24 3 views
-5

양식 10은 form11을 만들고 보여 주며 form11은 양식 12를 만들고 보여줍니다. 그런 다음 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. 
+2

초보자를위한 질문에 매우 만족하지만 답변을 읽고주의해야합니다. –

답변

4

변수 이름, 선언 및 사용에 더 많은주의를 기울여야합니다.

게시 한 코드에 Form11과 관련된 두 개의 완전히 다른 변수가 있습니다.

첫 번째

글로벌 Form11는 IDE에 의해 자동으로 추가됩니다 (당신이 있다면 삭제해야하지 그 첫 번째 장소에서 그 존재의 유일한 이유 때문에 양식을 자동으로 생성)을 선언, Unit11.pasinterface 섹션

:

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

var 
    Form11: TForm11 

두 번째는 당신이 당신의 버튼을 클릭 핸들러에서, Unit10.pas에 선언 fForm11라는 지역 변수

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에서 사용하는 하나 :

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

두 번째는 양식의 실제 인스턴스를 할당하고있는 한 당신이 만드는 것입니다

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; 

문제는 당신이 0의 인스턴스를 만든 적이 있다는 것입니다 : 액세스 위반이 코드에서 볼 수있는 유일한 사람입니다 글로벌Form11입니다및 Form11; 대신 범위를 벗어난 로컬fForm11에 생성하여 할당했습니다.

해결 방법은 다음과 같습니다. 로컬 변수를 제거하고 거기에서 작성한 양식을 적절한 변수에 지정하십시오.

그러나 당신을 위해 적절한 수정 프로그램은 매우 무모하게 장소 전체에서 몹시 싫증나 기 때문에 양식을 자동으로 만드는 것입니다. 이러한 모듈 간 의존성의 나쁜 사용으로 인해, 당신은 액세스하려고 할 때 생성되지 않는 문제를 반복하여 같은 유형의 문제를 반복하게 될 것입니다.

+0

도움을 많이 주셔서 감사합니다. 내 액세스 위반 문제를 해결하는 데 도움이되었습니다. – Owen

+2

@OwenH Ken의 답변을 수락하고 감사 카드의 왼쪽에있는 체크 표시를 클릭하여 감사를 표시 할 수 있습니다. –

관련 문제