C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[50474] Re:[Q] TForm의 유효기간?
장성호 [nasilso] 1570 읽음    2007-09-05 22:20
FormClose이벤트에서 Action=caFree 하면 자동으로 free됩니다.
즉 delete하실 필요가 없습니다.

그렇지만 님과 같이 delete하더라도 access voilation이 나지는 않는데....
좀 이상하네요

빈프로젝트에 Form 2개만 넣어서 테스트 해보십시요
그럼 에러가 없을것입니다.

무슨 다른곳에서 Error가 나는것 아닌가 생각합니다.

[추신]
<< OnClose에서 Action=caFree하고 또 delete하여도 Error가 나지 않는 이유 >>
     (  caFree메가니즘 )


아래는 TForm의 조상인 TCustomForm의
Close함수와 Release 함수, 그리고  CM_RELEASE메세지를 받아서 처리하는 함수의 VCL 코드입니다.

//--------------------------------------------------------------
procedure TCustomForm.CloseModal;
var
  CloseAction: TCloseAction;
begin
  try
    CloseAction := caNone;
    if CloseQuery then
    begin
      CloseAction := caHide;
      DoClose(CloseAction);            //    OnClose이벤트 핸들러 호출
    end;
    case CloseAction of
      caNone: ModalResult := 0;
      caFree: Release;                    // CloseAction = caFree이면 Release호출
    end;
  except
    ModalResult := 0;
    Application.HandleException(Self);
  end;
end;
//--------------------------------------------------------------
procedure TCustomForm.Release;
begin
  PostMessage(Handle, CM_RELEASE, 0, 0);        //이부분에서 바로 release하지 않고 PostMessage합니다.
end;
//--------------------------------------------------------------
procedure TCustomForm.CMRelease;
begin
  Free;                       //이부분에서 진짜로 release됩니다.
end;
//--------------------------------------------------------------

그런데 TCustomForm.Release함수에서  SendMessage가 아니고 PostMessage 입니다.
즉 곧바로 RELEASE되는것이 아니라 
현재 함수코드진행은 수행이 끝나고 즉 CloseModal함수가 끝나야 되구요
또한 ShowModal을 호출한곳에서 다음 코드가 있다면 그것이 수행이 끝날때까지
실제적으로 Handle은 release가 되지 않는것입니다.
님의  아래코드에서 delete가 호출된후에
다음 GetMessage가 호출되어야  CustomForm의 Handle이  CM_RELEASE 메세지를 받을수 있는데...
이미 delete에서 Handle이 없어졌으므로 CM_RELEASE 는 아무 의미가 없는 메세지가 되는것입니다.


아래와 같이 코딩하면 확실에 에러가 납니다.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Form2=new TForm2(this);
    int rslt=Form2->ShowModal();
    Application->ProcessMessages(); //이부분에서 CustomForm의 Handle이  CM_RELEASE 메세지를 받아 free됨
   delete Form2; //이미 free된것을 또 다시  free하려고 함  --> 이경우 여기서 반드시 에러가 남
}
//---------------------------------------------------------------------------

왜냐하면 Application->ProcessMessages 함수에서
TCustomForm.Release 에서 PostMessage한 메세지를
GetMessage로 가져와서 처리하게때문입니다.

[참고]
Form2는 아마 전역 변수일것입니다.

님과 같이 코딩하실때는 가능하면
TForm2 *frm=new TForm2(this); //이렇게 포인터변수를 선언해서 쓰는것이 안전합니다.


말이 많이 길어졌네요

결론적으로
님이 적어주신 코드에서는 직접적인 에러의 원인이 없습니다.
하지만 Action=caFree 나 delete둘중 하나만 쓰세요

그럼...


땅주인 님이 쓰신 글 :
: 메인 윈도우에서 여는 서브 윈도우의 Close Event에서 가지고 있던 Resource를 자동 해제하려고 이렇게 썼습니다.
:
: void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
: {
:     Action = caFree;
: }
:
: 근데, 메인 윈도우에서 Form2를 열고, 닫은 후에도 Form2의 변수 값에 접근할 수 있고,
: 그런데.. delete는 할 수 없고.. 이게 어찌된 영문 인 지?
:
: [ Main Window의 Button Event ]
:
: void __fastcall TForm1::Button1Click(TObject *Sender)
: {
:     TForm2 *pForm = new TForm2(this);
:
:     pForm->ShowModal(); // 모달 상자로 열었음.
:
:     k =pForm->m_ikk;         // Form2의 멤버에 접근이 가능함.
:
:     delete pForm;              // Access Violation나옴.
: }
:
: 변수값은 Access가능하고, Form를 delete할 때는 에러나고.. 속시원히 해결을 좀?
: Action = caFree이면 폼이 가지고 있던 모든 리소스도 해제되는 것 아닌가요?
:
: 그리고, 사실 다른 곳에서 썼던 스크립트는 위와 비슷한 코드인데.. delete pForm에서 전혀 에러를 내지
: 않고 잘 나갑니다. 가끔 프로그램이 Access Violation을 내는데..여긴 지 아닌 지는 잘 모르겠지만..
: 어쨌거나 잘 돌아가는 경우가 더 많다는 것이죠.. 좀 헷갈려서..... 속시원히 해결해 주실분 부탁해요..
:
: 감사합니다.

+ -

관련 글 리스트
50472 [Q] TForm의 유효기간? 땅주인 1344 2007/09/05
50474     Re:[Q] TForm의 유효기간? 장성호 1570 2007/09/05
50476         Re:Re:[Q] TForm의 유효기간? 우리 1662 2007/09/06
50480             Thanks..Thanks..Thanks... 땅주인 1381 2007/09/06
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.