Q&A

  • EAccessViolation. MDI Application
Project PageAlive.exe raised exception class EAccessViolation with message 'Access Violation at address 00000000. Read of address 00000000.' Process stopped. Use Step or Run to Continue.


메세지는 위와 같습니다.
전 MDIApplication 을 작성하고 있는데 MDIForm에서 툴바의 버튼을 클릭하면 MDIChild를 생성시키고 화면에 보여주는데, 이때 같은 폼이 중복되어서 나타나는 것을 막기위해서 체크를 하고 만약 폼이 현재 생성이 되어 있지 않으면 생성시킨 후 화면에 보여주고, 그렇지 않으면 열려있는 폼을 다시 제일 앞에 보여줍니다. 그런데 문제는 열려 있는 자식폼을 닫았다가 다시 그 폼을 열면 위의 에러가 발생합니다.(참고로 자식폼이 여러개 떠 있을때는 잘 작동합니다.)

소스를 첨부합니다.
=========================================
//접속소요시간 통계를 보여준다.
=========================================
procedure TMainForm.ToolButton2Click(Sender: TObject);
begin
        if Form5 <> nil then
                Form5.Show  //문제의 주범입니다.
                                    //아마 Form을 닫을때 메모리를 해제 시켜서
                                    //그런가봐요.
        else
        begin
                Form5:= TForm5.Create(Application);
                Form5.Show;
        end;
end;

이 대목에서 한가지 궁금한게 있습니다.
폼을 닫을 때 메모리를 해제하면 자동으로 객체의 값이 nil로 되지 않는지요?
안된다면 인위적으로 해줄 수 있는 방법은 없는지...


==========================================
//폼이 닫힐때 메모리 해제
==========================================
procedure TForm5.FormClose(Sender: TObject; var Action: TCloseAction);
begin
        Action := caFree;
End;


이 놈의 소스가 뭐가 문제일까요?
폼이 닫힐 때 메모리를 해제해서 그럴까요?
에러가 생기는 부분이 Form5가 nil이 아닐 때 Form5.Show에서 생깁니다.
java만 하다가 델파이는 시작한지 얼마 되지 않아서 아무리 봐도 이해가 잘 안되네요.
메모리 해제하면서 Form5에 nil값을 Assign시킬수는 없나요? 확실하게 nil값을 Assign시키면 될것 같기도 한데....
아니면 제가 방향을 잘 못 잡고 있는건가요?

폼이 닫힐 때 아무것도 하지 않으니 폼이 닫히지 않고 최소화가 되더군요.
그건 곤난합니다. 일단 폼을 종료시키면 폼은 화면에서 완전히 없어져야되고
나중에 다시 호출하면 생성되어서 화면에 나타나야합니다.

부디 선구자님들의 조언을 바랍니다.
조금 급하거든요. java Module은 개발이 끝났는데, 이놈의 Delphi가 속을 썩이니 환장하겄습니다. -.-;;
4  COMMENTS
  • Profile
    김강수 2002.03.05 10:26
    수고하십니다.
    방법이 없으시면 MDIChild 생성시 나오는 핸들을 이용하세요.

  • Profile
    유창원 2002.03.05 10:31
    Handle을 어떻게 이용하죠?
    좀만 더 상세하게 설명해 주시면 감사하겠습니다....
    (사실 TOOL이 약간 적응이 안됩니다. java가지고 일일이 코딩만 하다보니...)



  • Profile
    유창원 2002.03.05 11:06
    해결했습니다.

    =======================================
    //메모리 해제하는 부분
    =======================================
    procedure TForm5.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
            Form5 := nil;
            Action := caFree;
    End;

    위와 같이 하니까 에러는 안생기는데,
    메모리 해제하기 전에 객체의 참조를 끊어버리면
    결국은 메모리 해제가 안되는 거잖아요?
    제가 잘 못 생각하고 있나요?
    여기에 대해서 아시는 분 리플 좀 달아주시면 감사하겠습니다.
    아님 어떻게 메모리가 해제 되는지 테스트 해 볼 방법이 있으면 좋을텐테....

    모두들 즐코하세요.
    아시는분 꼭 좀 리플 부탁합니다.


  • Profile
    권경숙 2002.03.05 20:04
    Delphi 강의실에 이만준 님께서 올리신 "MDI 로 구현하는 MIS 프로젝트"라는 강의가 있습니다.

    한번 보시면 이 문제에 대한 다른 해결법이 있습니다.

    참고하시고 즐코하세요.