우리는 지금까지 WinMain의 메인 루프에서 GetMessage라는 함수를 통해 메시지를 받아 처리하였다. 그리고 스크린에 무언가를 그리기 위해서는 WM_PAINT라는 메시지가 들어올 때에만 처리하였다. 이것은 무엇을 의미하는가?! 맞다. WM_PAINT 메시지가 들어오지 않으면 화면에 그리는 작업을 하지 않는다는 것이다.
위에서 보는 것과 같이 PeekMessage는 GetMessage 함수와 유사하다. 가장 큰 차이점이 있다면 GetMessage 함수는 메시지가 도착하여야지만 리턴되는데 반해(blocking 함수임), PeekMessage 함수는 메시지 큐에 도착한 메시지가 없어도 그냥 리턴한다(non-blocking 함수임)는 점이다.
어떤가, 생각보다 간단히 끝나지 않았는가? 먼가 대단한 거라도 있는거 같더니... 달랑 몇 줄이다!!! 이제 위에서 실행해 보았던 코드에 PeekMessage가 포함된 버전을 다운로드 받아 실행해 보자. 아울러 위에서 실행해 보았던 두 예제와 비교해보자.
출처 : ht^2p://binul.lets'fly.com
게임과 같은 프로그램을 생각해보자. 게임과 같은 프로그램에서는 쉴새없이 스크린에 무언가를 그리는 작업을 한다. 당연히 쉴새없이 그려야지만 케릭터의 이동이나 다른 모든 화면의 움직임이 끊기지 않고 부드럽게 이어질 수 있는 것이다. 만약, 이러한 프로그램에서 GetMessage를 통해 메시지를 처리한다면 어떻게 될까? 결과는 불 보듯 뻔하다. 우리는 마우스를 한 손에 부여 잡고 (지속적으로 끊기는 화면에서) 로보트 춤을 추고 있는 우리의 느릿한 주인공을 조종하는데 지쳐 프로그램을 종료해 버릴 것이다. 아~ 대단히 비극적인 일이 아닐 수 없다. :)
하지만 고맙게도 현실은 그렇지 않다. 우리는 부드럽~게 움직이는 케릭터를 조종하며 온갖 화려한 마법을 쓰고 있다. 무엇이 이를 가능케 하는가?! 바로 PeekMessage 함수이다.
BOOL PeekMessage( LPMSG lpMsg, // MSG 구조체에 대한 포인터 HWND hWnd, // 윈도우에 대한 핸들 UINT wMsgFilterMin, // 첫번째 메시지 UINT wMsgFilterMax, // 마지막 메시지 UINT wRemoveMsg // 제거 플래그 ); |
- Parameters
- lpMsg: 메시지 정보를 받아올 MSG 구조체에 대한 포인터
- hWnd: 메시지의 대상 윈도우. -1로 지정되면 PeekMessage는 hWnd 값이 NULL인, 즉 PostThreadMessage에 의해 포스트된 메시지만을 리턴한다.
- wMsgFilterMin, wMsgFilterMax: 둘 다 0으로 지정하면 필터링없이 모든 메시지를 리턴한다. 만약, 모든 키보드 메시지를 받고 싶다면 각각 WM_KEYFIRST와 WM_KEYLAST로 지정하며, 모든 마우스 메시지를 받고 싶다면 각각 MOUSEFIRST와 WM_MOUSELAST로 지정한다.
- wRemoveMsg:
- PM_NOREMOVE: PeekMessage 수행 후에 메시지 큐에서 메시지가 제거되지 않음.
- PM_REMOVE: PeekMessage 수행 후에는 메시지 큐에서 해당 메시지가 제거됨.
- 이 외에도 PM_NOYIELD, PM_QS_INPUT, PM_QS_PAINT, PM_QS_POSTMESSAGE, PM_QS_SENDMESSAGE 등의 메시지가 있다. 자세한 내용은 MSDN을 참조하기 바란다.
다음은 PeekMessage 함수를 사용하여 메시지를 처리하는 예제이다.
BOOL bDone = FALSE;
MSG msg;
while(!bDone) {
// 메시지 큐에 메시지가 있으면 이를 처리하고, 없으면 while문 아래를 수행한다.
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if(msg.message == WM_QUIT) {
bDone = TRUE; // WM_QUIT를 받았으니 루프를 빠져나가자.
} else {
TranslateMesage(&msg);
DispatchMessage(&msg);
}
}
// 메시지 큐에 처리할 메시지가 없다. 화면이나 다시 그리자!
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
}
|
출처 : ht^2p://binul.lets'fly.com



댓글을 달아 주세요
음.. 잘 봤습니다만.. PeekMessage는 WM_QUIT을 받았을때 직접 break까지 해줘야 하는데..
break해주는 부분이 없네요. 윈도우는 종료되더라도 좀비프로세스로 남아있겠는데요..