GetMessage는 Windows 프로그래밍에서 윈도우 message loop을 구현할 때 쓰이는 함수이다.
이 함수는 명목상 리턴값이 BOOL이며, 평소에는 nonzero를 되돌리다가 WM_QUIT가 접수되어서 응용 프로그램이 종료되어야 할 때 FALSE가 된다.

그러나 이 함수의 리턴값이 이것이 전부가 아니다.
정상적으로 한 메시지를 끄집어 왔을 때는 nonzero이긴 한데 양수이며, argument가 올바르지 않다거나 해서 함수의 실행 자체가 실패했을 때는 음수 -1을 되돌린다.

그렇기 때문에 메시지 loop을 while( GetMessage(&msg, NULL, 0, 0)) { }  이런 식으로 구현하면, 메시지를 아예 가져오질 못했는데도 loop의 조건이 만족되며 프로그램은 무한 루프에 빠진다.
!=0으로는 불충분하니, 반드시 while( GetMessage(&msg, NULL, 0, 0) >0)이라고... >0을 명시해야 한다.

(1) 이 함수 말고도 타입이 BOOL인데 사실은 TRUE/FALSE라는 순수한 흑백 논리값 말고 다른 의미 있는 값도 되돌리는 페이크 BOOL 함수가 또 있었던 것 같으나, 당장은 기억이 안 난다. 이런 지저분한 이슈도 있고, 또 Windows API의 기반 언어인 C가 어지간한 건 그냥 machine word 정수로 처리하는 관행이 있기도 하니(문자 상수의 크기도 char이 아닌 int!), 프로그래밍에서도 BOOL은 C++의 bool이 아니라 그냥 int에다 대응시켜 놓은 것 같다.

(2) COM에도 이와 비슷한 얘깃거리가 있다. HRESULT는 원래 0과 양수가 '성공'을 나타내고, 음수가 실패를 나타낸다. 하지만 현실에서는 대부분 그냥 hr==S_OK (0) 여부만으로 성공/실패 여부를 판단한다.
거의 모든 COM 인터페이스 함수들은 실행이 성공했을 때 어차피 S_OK라는 단일한 값만을 되돌리기 때문에 이것이 현실에서 당장 크게 문제가 되지는 않는다. 그러나 원칙적으로는 어지간해서는 hr==S_OK를 쓸 곳에 SUCCEEDED(hr)을 써야 한다. 이것은 hr>=0 여부를 체크하는 매크로이다. hr!=S_OK를 대신해서는 FAILED(hr)이 바람직하고 말이다.

음수도 아니고 0도 아닌 대표적인 리턴값은 S_FALSE이다. 이것은 해당 함수가 의미 있는 동작을 하지는 않았지만 어쨌든 오류가 발생했거나 실패한 상황도 아닐 때 돌아온다. 가령, 뭔가 객체를 enum하고 있는데, 포인터가 이미 끝에 도달해서 더 fetch할 게 하나도 없으면 보통 &ulFetched는 0이 돌아오고 함수 리턴값은 S_FALSE가 된다. 하나라도 fetch된 게 있으면 S_OK이고 말이다.
따라서 이 경우, loop의 종료 조건을 지정하려면 SUCCEEDED와 더불어 fetch된 개수도 체크해야 한다.

(3) 다시 GetMessage 얘기로 돌아온다.
얘는 메시지를 수집하는 윈도우, 그리고 필터링할 메시지의 최소값과 최대값을 인자로 받는다. 하지만 PeekMessage도 아니고 GetMessage에다가 뭔가 동작의 범위를 제한하는 유의미한 값을 지정하는 것은 사실상 거의 쓸데없는 짓이다. 언제나 NULL, 0, 0을 하는 게 맞다. (레이몬드 챈 선생도 인증한 사실임)

이 함수는 뭔가 메시지를 얻을 때까지 실행이 끝나지 않고 계속 기다린다. 어떤 GUI 프로그램이 실행되면 굳이 자신이 아니어도 그 스레드 소속으로 남이 생성한 각종 잡다한 윈도우가 붙는다. 이들 윈도우도 메시지 큐로부터 메시지를 받아야 하는데, GetMessage에다가 필터링을 걸면 해당 윈도우는 메시지를 받지 못하며 그 동안 우리 프로그램도 실행되지 못하게 된다. 쉽게 말해 deadlock에 빠진다.

따라서 아무 윈도우로 전달된 아무 메시지라도 일단은 받아서 윈도우 프로시저로 Dispatch를 시켜야 한다. 정 특정 메시지만 필터링을 하고 싶다면 아까도 말했듯이 PeekMessage를 쓰는 게 훨씬 더 안전하고 바람직하다. 얘는 그래도 한 번만 체크 후 실행이 곧장 끝나기라도 하니까 말이다.

Posted by 사무엘

2014/04/30 08:31 2014/04/30 08:31
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/957

Trackback URL : http://moogi.new21.org/tc/trackback/957

Leave a comment
« Previous : 1 : ... 789 : 790 : 791 : 792 : 793 : 794 : 795 : 796 : 797 : ... 1641 : Next »

블로그 이미지

철도를 명절 때에나 떠오르는 4대 교통수단 중 하나로만 아는 것은, 예수님을 사대성인· 성인군자 중 하나로만 아는 것과 같다.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2020/07   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Site Stats

Total hits:
1403393
Today:
308
Yesterday:
520