한국어
Windows Programming

MFC 대화상자 종료 메시지 호출 순서

pjk 2014.06.19 09:25 조회 수 : 3613

"메시지 처리에 대해서 잘 알고 있다면 다음 내용이 필요 없다."

MFC에서 기본적인 위도우 프레임웍이 설계되어 있고 그 곳에 맞게 필요한 코드를 넣어주면 된다.
프로그래밍에 있어서 가장 중요한게 자원 할당과 해제이다. 특히 C++에서는 메모리 관리를 프로그래머가 직접해주기 때문에 잘못된 메모리 관리는 시스템 전체에 안좋은 영향을 준다.

MFC에서  가장 무식하게 자원 할당과 해제를 하는 경우를 보면 생성자와 소멸자에 하는 경우이다. 실제 직접 생성자와 소멸자에 코딩하는 경우는 드물고 포인터 변수를 NULL로 초기화하는 정도이다.

그럼 MFC에서 실제 API 호출 순서를 보자. 응용프로그램 형태 중에서 대화상자를 중심으로 살펴보겠다.


Case 1) 대화상자 뛰우고 [X] 버튼  눌러 종료하기

Warning: no message line prompt for ID 0x8003.
[CD1Dlg] PreInitDialog()
[CD1Dlg] OnInitDialog()
[CD1Dlg] OnClose()
[CD1Dlg] OnCancel()
[CD1Dlg] OnDestroy()
[CD1Dlg] PostNcDestroy()
[CD1Dlg] OnNcDestroy()

Case 2) 대화상자 뛰우고 "Cancel"  버튼 눌러 종료하기

Warning: no message line prompt for ID 0x8003.
[CD1Dlg] PreInitDialog()
[CD1Dlg] OnInitDialog()
[CD1Dlg] OnCancel()
[CD1Dlg] OnDestroy()
[CD1Dlg] PostNcDestroy()
[CD1Dlg] OnNcDestroy()

Case 3) 대화상자 뛰우고 "Ok" 버튼 눌러 종료하기

Warning: no message line prompt for ID 0x8003.
[CD1Dlg] PreInitDialog()
[CD1Dlg] OnInitDialog()
[CD1Dlg] OnDestroy()
[CD1Dlg] PostNcDestroy()
[CD1Dlg] OnNcDestroy()

* 처음

위의 경우를 살펴보면, 처음 시작시 호출되는 함수가,

PreInitDialog()
OnInitDialog()

두 함수가 기본적으로 호출이 된다. OnInitDialog 함수는 많이 익숙한 이름이다. 대화상자에 가장 기본적인 초기화 코드를 넣는 함수이다.

(함수라는 용어보다 메소드, API, 멤버 함수등을 적합한 이름을 선택해야되는데 편의상 쉽게 이해하기 위해서 함수로 통일한다.)

** 중간

그리고 종료하는 종류에 따라서 중간에 호출되는 함수가 달라진다.

[X]와 "Cancel" 버튼을 눌렀을 경우에 공통적으로 OnCancel 함수가 호출된다. 단, [X] 버튼을 눌렀을 경우 추가로 OnClose 함수가 호출된다.
간혹 OnClose 함수가 대화상자 닫히는(Close) 경우로 착각해서 이 곳에 넣는 경우가 있다. 나도 그런 적이 있었다. 위의 함수 호출 순서에 나왔듯이 OnClose 함수는 경우에 따라서 호출되지 않은다.
"Ok" 버튼을 눌렀을 경우는 역기서는 별다른 함수 호출이 없다. 필요하다면 OnOk 함수 정도 정의하면 된다.

*** 끝

종료하는 경우는 살펴보자.

OnDestroy()
PostNcDestroy()
OnNcDestroy()

세 종류의 함수가 호출된다. OnDestroy 함수는 메시지 핸들러로 WM_DESTROY 메시지를 수신하면 호출된다.
PostNcDestroy 와 OnNcDestroy 는 함수 재정의에 의해서 사용된다.
종료시 가장 많이 사용하는 함수가 OnDestroy와 OnNcDestroy 함수이다.
본인이 선호하는 것은 OnDestroy 함수이다. OnNcDestroy()는 함수를 재정의 해줘야하며 메시지 종료 (WM_DESTROY)에 의해서 종료될 경우 해당 자원 해제를 확인하는데 직관적이지 않기 때문이다.