일반적인 윈도 소멸 순서
MFC framework에서, 사용자가 frame 윈도를 닫게되면, 윈도는 기본적으로 OnClose 핸들을 call 한다. OnClose 내부에서는 DestroyWindow를 호출한다. 가장 마지막으로 호출되는 함수는 OnNcDestroy이다. 이 함수는 약간의 정리를 하는 함수로 윈도를 정리하기 위하여 기본적으로 불려지는 함수 이다. OnNcDestroy함수 내부에서는 PostNcDestroy함수를 호출한다.
afx_msg OnClose( )
Framework은 CWnd나 application을 종료 시키기 위해서 이 함수를 마치 시그날 처럼 호출한다. 내부의 기본적인 구현은 DestroyWindow를 호출한다.
virtual BOOL DestroyWindow( )
Destroy Window 함수는
하지만 아직 CWnd 객체는 destroy하지 않는다.
이 함수를 오버라이드 하더라도 이 함수를 호출하지 않아도 된다. ( 왜냐면 시스템이 알아서 호출을 해주니까..) 뭐 굳이 하고 싶다면 해도 된다. 만약 내부에 자식 윈도가 있더라도 걱정하지 말자 자식들을 먼저 destroy한 다음에 자신이 죽으니까....
afx_msg void OnDestroy()
Framework이 CWnd에게 현재 CWnd가 소멸되고 있는 중이라고 알려 주기위하여 호출 한다. OnDestroy함수는 CWnd 함수가 화면에서 사라진 다음에 호출된다.
OnDestroy is called first for the CWnd being destroyed, then for the child windows of CWnd as they are destroyed. It can be assumed that all child windows still exist while OnDestroy runs.
afx_msg void OnNcDestroy()
Client가 아닌 영역이 destroy될 때 Frame work에 의하여 불려지는 함수이다. 윈도가 소멸될때 마지막으로 불려지는 함수이다. 기본적으로 약간의 정리를 한후, PostNcDestroy 함수를 호출한다. 대게는 이 함수를 오버라이드 하지 않지만 만약 하게되면 내부에서 상위 클래스의 OnNcDestroy를 호출해야만 한다. 그렇지 않으며녀 내부적으로 윈도를 위해 할당된 메모리가 free되지 못한다.
virtual void PostNcDestroy()
윈도가 소멸된 후 OnNcDestroy함수에 의하여 불려지는 기본함수이다. 사용자들이 상속받아 만든 클래스의 정리를 위한 코드를 삽입하면 된다. ( ex. delete this; )
위의 함수를 그냥 대충 보지 않고 세심히 본 사람이라면 이제 자신이 삽입하기를 원하는 코드를 어느부분에 삽입을 해야되는지 알 수 있을 것이다. 그럼 아래의 예를 통하여 알아보자.
먼저 View class에서는 3가지 소멸 핸들러를 제공한다. 다음을 보자.
BOOL CAniView::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
return CView::DestroyWindow();
}
void CAniView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
}
void CAniView::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
CView::PostNcDestroy();
}
위에 나열 된 순서가 바로 view가 닫힐 때 불려지는 순서이다. 우리가 유심히 살펴 보아야할 부분은 TODO의 위치이다. 과연 어떤 이유에서 각각의 TODO의 위치가 결정 되는가?
만약 윈도가 없어지기 전에 작업을 해야할 일이 있다면 4번 중에 코드를 삽입하자. 또한 윈도가 사라진 다음에 작업을 해야 한다면 22번 줄에 삽입을 한다. delete this 함수를 사용한다면 25번째 줄에 삽입하자.
view에서는 제공되지 않지만 OnClose 함수도 TODO의 위치를 잠시 보자.
void CAboutDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
CDialog::OnClose();
}