저 하늘의 구름처럼~

SendMessage와PostMessage의 차이점,SendMessage의 문제점 본문

WIN32 API

SendMessage와PostMessage의 차이점,SendMessage의 문제점

강백호v 2009. 1. 19. 21:21
PostMessage의 경우 윈도우의 메시지 큐에 메시지가 들어가게 되고, 윈도우 프로시저에게 이메시지
를 처리하도록한다. 메시지를 큐에 넣기만 하고 바로 리턴하므로 메시지를 붙인 후 즉시 다른 작업
을 할 수 있게 되지만 큐에 대기하고 있는 다른 메시지가 있으면 뒤에 붙인 메시지는 곧바로 처리되지 않는 특징을 가지고 있다.큐에 붙여진 메시지는 GetMessage에 의해 읽혀지고,DispatchMessage 함수에 의해 윈도우 프로시저로 보내어져 처리가 된다.SendMessage는 메시지를 큐에 넣는 것이 아니라 곧바로 윈도우 프로시저로 보내 즉각 처리하도록 하며 메시지가 완전히 처리되기 전에는 리턴하지 않고, 블록 시켜서 대기 상태로 만든다.정리해보면, SendMessage는 메시지를 바로 처리하고,PostMess
age는 메시지 대기 큐에 넣어서 처리를 하는 것이다. SendMessage의 동작 과정에 대해 알아보도록 하겠다. SendMessage()를 호출한 스레드와 메시지를 받는 윈도우를 생성한 스레드가 같다면 실제로 SendMessage() 는 직접 윈도우 프로시저를 호출한 것과 크게 다르지는 않다.
하지만 다른 스레드가 생성한 윈도우에게 보내는 경우라면 다음과 같은 단계를 거치게 된다.
1. 메시지를 받는 윈도우를 생성한 스레드의 Sent Message Queue에 메시지가 추가된다.
( 이는 QS_SENDMESSAGE 플레그를 세팅한 효과를 가지는 것이다.)
2. 받는 스레드가 다음 번 메시지를 받아올 준비가 되었을 때, QS_SENDMESSAGE 플래그가 세팅되어 있다면 Sent Message Queue에서 메시지를 꺼내어 온다.
3. 메시지 핸들러의 처리가 끝나면 메시지를 보낸 스레드의 Reply Message Queue에 결과를 추가한다.
4. 메시지를 보낸 스레드는 자신의 Reply Message Queue에 메시지가 들어올 때까지 기다리고 있게 된다. 이제 새 메시지가 들어왔으므로 넘겨온 값과 함께 SendMessage() 를 반환하게 된다.Send
Message함수의 경우 이러한 처리 과정을 거치게 된다.

SendMessage함수의 경우, 윈도우 프로시저가 작업을 끝내게 되면 반환 하도록 되어있는데, 이것은작성하고자하는 managed code상에서 예상치 않은 익셉션이 발생한다면, 실행은 SendMessage 함수 호출을 통해 리턴할 수 없게 되어, 시스템이 죽어버리는 상태를 유발하게 된다. 이러한 문제점을 해결하기 위한 함수가 SendNotifyMessage가 있다. 이와 유사한 함수들로, SendMessageTimeout(),SendMess
MessageCallback(),ReplyMessage()가 있다.
SendNotifyMessage()함수에 대해서 msdn에서는 다음과 같이 언급 하였다. 특별한 메시지를 윈도우 혹은 윈도우들에게 보낸다. 만약에 윈도우가 동일 스레드에서 호출되어 생성된다면, SendNotify
Message는 윈도우 프로시저를 호출하고, 윈도우가윈도우 메시지를 받아서 처리하는 동안 반환 하지 않는다. 하지만, 윈도우가 다른 스레드에게 호출 되면, SendNotfiyMessage는 메시지는 윈도우 프로시저로 보내고, 즉시 반환한다. 이것은 윈도우 프로시저가 메시지의 처리를 끝내기를 기다려 주지않는다는 의미이다.이러한 특성 때문에, SendMessage 함수를 사용하는 것 보다는 SendNotfiyMessage함수를 사용하는 편이 시스템에 좀더 안정할 것이라 생각 되어 진다.

- 참고 문헌 : Win32 API 완전 정복,김상형 저
- 참고 블로그 : http://www.webdizen.net/blog/entry/SendMessage%B4%C2-%BE%EE%B6%BB%B0%D4-%C0%DB%B5%BF%C7%CF%B4%C2%B0%A1