2014-02-20 4 views
-4

Form1 생성자 Create가 Form1의 모든 구성 요소를 채우는 작업을 완료하면 Form1.OnCreate 이벤트 처리기 절차에서 확인하고 싶습니다. 그런 다음 Form1을 사용하여 구성 요소를 반복하고 Text 속성을 변경하려고합니다. 시도 :Delphi XE5 - TForm.OnCreate()를 기다리는 동안 구성 요소의 채우기가 완료되었습니다.

WHILE NOT Assigned(Form1) DO 
    Sleep(100); 

...하지만 작동하지 않았습니다.

이제 Form1을 사용하려고하면 액세스 위반 오류가 발생합니다.

+0

실제로 무엇을하려고합니까? 기다리는 것이 해결책이 아니라고 확신합니다. 모든 코드가 동일한 스레드에서 실행된다는 것을 이해해야합니다 (필자는 생각합니다). 그리고 당신은 자신을 기다릴 수 없습니다. –

+2

인스턴스가 아닌 클래스에 액세스하려는 것 같습니다. 클래스는 TForm1, 인스턴스 변수는 Form1이라고합니다. 클래스에 배정 된 멤버는 사용할 수 없습니까? – whosrdaddy

+2

'Assigned (Form1) do Sleep (100) do '도 도움이되지 않습니다. 그것은 결코 끝나지 않는 고리입니다. 나는 당신이 진짜 문제를 설명 할 것을 촉구한다. –

답변

5

OnCreate 이벤트는 Form 개체의 생성이 끝날 때 트리거됩니다. 양식의 구성 요소는 구성 프로세스 중에 생성되어 OnCreate 이벤트가 트리거됩니다. "check ... Form1 생성자 Create이 작업을 완료하면" 기본적으로 보장됩니다. OnCreate이 트리거되면 구성 요소에 액세스 할 수 있습니다. 당신의 Form1 객체가 프로그램 시작시 TApplication.CreateForm()를 통해 생성 된 경우

은 생성자를 호출하기 전에 다음 Form1 변수는 유효하지만, 초기화되지 않은 객체를 할당됩니다, 따라서 OnCreate 경우에 유효한 물체를 가리 킵니다.

코드에서 해당 생성자를 호출하여 Form1 개체를 만든 경우 Form1 변수는 생성자가 종료 될 때까지 할당되지 않으므로 OnCreate 이벤트의 유효한 개체를 가리 키지 않습니다.

어느 쪽이든 Form1 개체를 시작하려면 이벤트의 내부에서 Form1 변수를 사용하면 안됩니다. 대신 Self 포인터를 사용하거나 이벤트의 Sender 매개 변수를 입력합니다. 두 개체 모두 동일한 Form1 개체를 가리 킵니다.

+0

감사합니다. 중요하고 유용한 정보도 많이 있습니다. –

5

이 답변은 내 의견에서 명백하게 드러난 것처럼 실제 문제라고 생각하는 주소에 답변합니다. 현재 질문에 나타나는 세부 정보 만 포함하도록 질문을 편집해야합니다.

양식을 만들 때마다 프로 시저를 실행하려고하는 것처럼 보입니다. 위에서 설명한대로 주 스레드에서 기다리지 않아도됩니다. 대기중인 것은 메인 스레드에서도 실행됩니다. 너는 영원히 막을거야.

그래서 나는 결코 기다릴 수없는 방법을 설명하려고하지 않겠습니다. 그것은 실제 문제에 대한 해결책이 아닙니다.

귀하의 문제를 이해하고 귀하의 최근 질문에 따라 해당 양식의 생성자에서 Application.MainForm에 액세스하려하고 MainForm 속성이 아직 초기화되지 않았습니다. 그 이유는 Application이 소유 한 모든 구성 요소를 살펴보고 싶어하기 때문입니다.

또는 양식을 만드는 동안 nil 인 글로벌 Form1 변수를 사용하려고합니다. 그러나 어쨌든 해당 글로벌 Form1 변수를 삭제하는 것이 좋습니다. 전역 변수는 문제를 일으키는 경향이 있습니다. 양식의 메서드 내부에 있으므로 OnCreate의 메서드 처리기에서 Self을 사용하여 양식에 액세스 할 수 있습니다. 가능하면 Self을 사용하십시오.

하지만 어쨌든 문제를 해결하는 것은 잘못된 방법입니다. 그것은 프로그램이 시작된 후에 생성 된 양식의 존재를 부인합니다. 양식 작성시 필요한 경우 수행해야하는 작업을 수행해야합니다.

  1. 는, 예를 들어, TMyBaseForm라고 TForm에서 파생 된 새로운 형태를, 선언 :

    내가 문제를 해결할 방법이다.
  2. override 지시문을 사용하여 AfterConstruction 절차를 추가하십시오.
  3. TMyBaseForm.AfterConstruction을 구현하여 텍스트 변경 코드를 호출하십시오. 이 시점에서 모든 디자인 타임 컨트롤이 존재하며 속성이 스트리밍됩니다.
  4. 응용 프로그램의 모든 양식이 TMyBaseForm에서 파생되었는지 확인하십시오.

이 디자인은 프로그램의 모든 GUI 요소에서 일관된 동작을 적용 할 수있는 기회를 제공합니다.

최종 의견 1 개. 당신은 상대적으로 미숙하고 초보자 인 것처럼 보입니다. 괜찮습니다. 우리는 한 번 모두 거기있었습니다.그러나 제안 된 해결책에 대해서가 아닌 문제에 대해 질문하는 것이 더 성공적 일 것입니다.

+0

수락 해 주셔서 감사합니다. 나는 네가 옳다고 생각하기를 바란다. 질문을 편집하여 내가 진정으로 의미하는 바를 묻는다면 감사 할 것입니다. –

+0

감사합니다, 당신은 델파이시의 신입니다 ;-) 희망 편집은 지금 괜찮습니까? –