WndProc
메시지 처리 함수란 메시지가 발생할 때 프로그램의 반응을 처리하는 일을 하며 WinMain 함수와는 별도로 WndProc이라는 이름으로 존재한다. 윈도우 프로시저(Window Procedure)라는 뜻이지만 통상 읽을 때는 "윈드프록"이라고 읽는다. WndProc은 WinMain에서 호출하는 것이 아니라 윈도우즈에 의해 호출된다. WinMain내의 메시지 루프는 메시지를 메시지 처리 함수로 보내주기만 할 뿐이며 WndProc은 메시지가 입력되면 윈도우즈에 의해 호출되어 메시지를 처리한다. 이렇게 운영체제에 의해 호출되는 응용 프로그램내의 함수를 콜백(CallBack) 함수라고 한다.
WndProc의 인수는 모두 4개이며 MSG 구조체의 멤버 4개와 동일하다. hWnd는 메시지를 받을 윈도우의 핸들이며 iMessage는 어떤 종류의 메시지인가, 즉 어떤 변화가 발생했는가에 관한 정보를 가진다. iMessage가 WM_MOVE이면 윈도우의 위치가 변경되었음을 알리고 WM_DESTROY이면 윈도우가 파괴되었음을 알리는 것이다.
wParam, lParam은 iMessage의 메시지에 따른 부가적인 정보를 가진다. 예를 들어 마우스 버튼이 눌러졌다는 WM_LBUTTONDOWN 메시지가 입력되었다면 화면의 어디쯤에서 마우스 버튼이 눌러졌는가, 그때의 키보드 상황(Shift, Ctrl, Alt)은 어떠한가에 관한 정보가 추가로 필요하며 WM_CHAR 메시지, 즉 키보드로부터 키가 입력되었다는 메시지가 입력되었다면 어떤 키가 입력되었는가에 관한 추가적인 정보가 필요하다. 이런 추가 정보들이 wParam, lParam으로 전달된다. wParam, lParam에 실제로 어떤 값을 전달되는지는 메시지별로 다르다.
WndProc의 구조는 대체로 다음과 같은 형태를 가진다. 메시지의 종류에 따라 다중 분기하여 메시지별로 처리를 진행한다.
switch(iMessage)
{
case Msg1:
처리1;
return 0;
case Msg2:
처리2;
return 0;
case Msg3:
처리3;
return 0;
default:
return DefWindowProc(...);
}
Msg1 메시지가 전달되면 처리1을 한 후 리턴하고 Msg2 메시지가 전달되면 처리2를 한 후 리턴한다. case문은 프로그램이 처리할 메시지의 수만큼 반복될 것이다.
제일 끝에 있는 DefWindowProc 함수는 WndProc에서 처리하지 않은 나머지 메시지에 관한 처리를 해 준다. 예를 들어 시스템 메뉴를 더블 클릭하면 프로그램이 종료되는데 이런 처리는 별도로 해 주지 않아도 DefWindowProc 함수에서 해 준다. 그래서 윈도우의 이동이나 크기변경 따위의 처리는 직접 해 줄 필요없이 DefWindowProc으로 넘겨주기만 하면 된다. First 예제의 메시지 처리 함수는 다음과 같이 되어 있다.
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
switch(iMessage) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
WM_DESTROY 메시지만을 처리하고 있으며 나머지 메시지에 대해서는 DefWindowProc에게 맡긴다. WM_DESTROY 메시지는 사용자가 시스템 메뉴를 더블클릭하거나 Alt+F4를 눌러 프로그램을 끝내려고 할 때 발생하는 메시지이다. WndProc에서 이 메시지가 발생하면 PostQuitMessage 함수를 호출하여 WM_QUIT 메시지를 보낸다. WM_QUIT 메시지가 입력되면 메시지 루프의 GetMessage 함수 리턴값이 False가 되어 프로그램이 종료된다.
WM_DESTROY 이외의 메시지는 모두 DefWindowProc 함수로 전달되며 이 함수에서 디폴트 처리를 수행해 준다. WndProc은 메시지를 처리했을 경우 반드시 0을 리턴해 주어야 한다. 또한 DefWindowProc 함수가 메시지를 처리했을 경우 이 함수가 리턴한 값을 WndProc 함수가 다시 리턴해 주어야 한다.
출처: http://www.soen.kr/