#2. 메시지 전달
메시지 처리를 위한 전형적인 메시지 루프는 다음과 같다.
1
2
3
4
while (GetMessage(&msg, NULL, 0, 0)) { // WM_QUIT 까지 루프 실행
    TranslateMessage(&msg);  // 메시지 번역, WM_KEYDOWN이 WM_CHAR로...          
    DispatchMessage(&msg);  // 윈도우 프로시저 실행
}
GetMessage() 함수는 메시지 큐에 메시지가 있으면 메시지를 꺼내 오고 그렇지 않으면 대기한다. 꺼내온 메시지는 TranslateMessage() 를 통해 적절한 메시지로 번역되고, DispatchMessage()에 의해 윈도우 프로시저로 전달된다.
윈도우즈 시스템은 윈도우 프로시저에 메시지를 전달하는데 있어서 다음의 두가지 방식을 사용한다.
- 
    
Queued Message :
WM_QUIT,WM_PAINT,WM_TIMER로서 메시지 큐에 메시지들이 적재되어 있다가 적절한 시점에 처리된다. 특히WM_PAINT는 동일한 윈도우에 대하여 하나의 메시지로 통합되고, 메시지 큐가 비워졌을때 처리된다.(이때 여러Invalid영역은 하나로 합쳐질 것이다.)이 때문에 화면 갱신의 횟수가 줄어든다. - 
    
NonQueued Message : 기타 다른 메시지
 
메세지 큐는 Thread 생성시 자동으로 만들어 진다.
- 
    
TranslateAccelerator()로 메시지 루프에서 단축키를 선처리할 수 있다.1 2 3 4 5 6 7 8
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MY_ACCEL); while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
 - 
    
PeekMessage()로 메시지 큐의 내용을 검사할 수 있다. - 
    
GetMessageTime()으로 메시지가 발생한 시간을 알 수 있다. - 
    
GetMessagePos()로 메시지가 발생했을 때의 커서 위치를 알 수 있다. - 
    
WaitMessage()로 메시지가 발생할 때까지 대기할 수 있다. - 
    
PostMessage(),PostThreadMessge()로 메시지 큐에 메시지를 추가 할 수 있다. 이때 메시지가 어떻게 처리되었는지의 응답을 기다리지 않는다. 이함수로 메시지를 큐에 넣고, 메시지 루프에 해당 메시지를 처리하는 루틴을 작성한다면, 윈도우 없는 어플리케이션을 작성할 수도 있다. - 
    
PostQuitMessage()로WM_QUIT를 메시지 큐에 넣을 수 있다. - 
    
SetMessageExtraInfo(),GetMessageExtraInfo()로 특정 메시지에 대한 부가 정보를 사용할 수도 있다. - 
    
SendMessage()로 윈도우 프로시저에 직접 메시지를 전송할 수 있다. 이때 메시지가 10떻게 처리되었는지 응답을 기다린다. - 
    
SendMessageTimeOut()으로 메시지의 응답을 주어진 시간만큼 기다리게 할 수 있다. - 
    
SendNotifyMessage()로 메시지의 응답을 기다리지 않게 할 수 있다. - 
    
InSendMessage(),ReplyMessage()로 메시지 처리에 대한 응답을 빨리 해줄 수 있다.1 2 3 4 5 6
case WM_USER + 1: if (InSendMessage()) { ReplyMessage(TRUE); // SendMessage()가 기다리지 않게 일단 빨리 응답 } //.... 시간이 좀 걸리는 작업.... break;
 
Send 계열의 메시지 전송 함수는 윈도우 프로시저에 직접 메시지를 전송하고, Post 계열의 메시지 전송 함수는 메시지 큐에 메시지를 추가한다는 사실을 유의할 것. Post 계열은 메시지 큐가 꽉 차면, 실패할 수 있다.
댓글남기기