본문 바로가기

프로그래밍 오류해결

MFC프로그램 종료시 유의할점.

흔히 윈도우 프로그램을 하면서 보게되는 책이 API관련 책들이나, MFC관련책들을 접하게 될것이고, 프로그램을 하게 될것입니다. 흔히 생각할때 대부분의 기초적인 윈도우 프로그램의 예제에서는 PostQuitMessage를 이용하여 프로그램을 종료하는 경우가 많고, 나또한 이것이 프로그램을 종료하는 방법중 하나일것이라 생각하고 사용해 왔습니다.

하지만 이것은 이번에 학과 과제로 만드는 프로그램에서 메모리릭을 발생시키는 주된 원이이었고.. 이 문제를 해결하기위해 자료를 검색하던중 PostQuitMessage의 문제점과 다른 종료방법에 대해서도 알수 있었습니다.

아래는 참고한 자료중 프로그램을 종료하는 방법들을 나열한 것입니다.(출처: http://devkyy.tistory.com/203)

* TerminateProcess
ㄱ. 자기 자신이 아닌 다른 프로세스를 종료시킬 수 있음.
ㄴ. 정리 작업을 하지 않기 때문에 되도록 사용하지 않는 것이 좋음.
ㄷ. 메모릭 발생 위험 있음.

* PostQuitMessage
ㄱ. 단지 메시지 맵에 WM_QUIT 메시지만 전달하는 것이기 때문에 
   이 명령의 다음 코드도 실행이 됨.
ㄴ. 메모릭 발생 위험 있음.
   
* ExitProcess
ㄱ. 프로세스와 연결된 모든 DLL을 종료시키기 위해 
   각 DLL의 DllMain함수가 호출되며 DLL들은 스스로 정리작업을 시도함.
ㄴ. 모든 열려진 핸들을 닫음.(핸들 테이블 제거)
ㄷ. 프로세스 커널 객체와 쓰레드 객체의 상태가 신호상태로 되며 
   이 신호를 기다리는 다른 프로세스 대기 상태를 해제할 수 있음.
ㄹ. 프로세스의 종료코드는 STILL_ACTIVE에서 ExitProcess()인자로 지정한 값으로 변경됨.
ㅁ. 곧바로 정리 작업에 들어가기 때문에 이 명령 뒤의 코드는 실행되지 않음.
ㅂ. 실행중인 모든 쓰레드를 종료시킴.
ㅅ. 메모리 릭 발생 위험 적음.

그리고 다음은, winapi사이트에서 답변으로 달린 게시글입니다. 자세하게 풀어놓았더군요.

그리고 아래는 MFC의 View 클레스에서 프로그램을 종료하는 방법입니다.
전 이것을 참고로 메모리릭 문제를 해결했습니다.

SDI(single document interface)

GetParent()->SendMessage(WM_CLOSE); 

MDI(multiple documents interface)

AfxGetMainWnd()->SendMessage(WM_CLOSE); 

 BeginWaitCursor(); 등 종료를 해주어야 하는 게 있다면 SendMessage 보다 PostMessage로 보내는 것이 맞습니다. 

sendmessage 할 경우 수행되는것은

beginwaitcursor -> close(메인프레임의 종료) -> endwaitcursor(여기에서 에러 발생) 

postmessage 할 경우 수행되는것은

beginwaitcursor -> post close(메인프레임의 종료 예약) -> endwaitcursor -> 실제 close