C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[3191] Re:[질문] 메세지맵의 문법적의미를 알고 싶습니다.
박지훈.임프 [cbuilder] 4257 읽음    2000-03-24 00:00
D빌더 님이 쓰신 글 :
: ^_^ 안녕하세요.
:
: 질문을 할때마다 성의껏 답변해주시는 모든분들께
: 감사를 드립니다.
:
: 이번질문은 메세지맵에 관한것입니다.
: 예를 들면 다음과 같은 문장이 있습니다.
: MESSAGE_HANDLER(WM_ERASEBKGND,TWMEraseBkgnd,WMEraseBkgnd)
: 각각은 무엇을 의미하는것인가요?
:
: 그리고 실전에서 어떤 메세지를 사용하고 싶다고 한다면
: 메세지에 관련된 자료는 무엇을 참조하면 될까요.



임펠리테리입니다.

다른 게시판에서도 몇번 답변했던 내용이기에.. 제가 하이텔 비파툴에서 답변했던 내용을 그대로 올립니다.


제  목:[답변] Dispatch() 함수에 관하여....            관련자료:없음
보낸이:박지훈(cbuilder)    1999-01-04 15:46  조회:67   1/5
───────────────────────────────────────
임펠리테리입니다.

모든 메시지가 처리되는 곳은 궁극적으로 Dispatch() 함수입니다.
저번에 언급한 적이 있는 WndProc() 조차도 마지막에서는 Dispatch() 함수를
호출합니다.
그러니까 디폴트 메시지 처리를 위한 루틴은 모두 Dispatch() 함수 내에 있는
것입니다.
그리고 당연히 상속관계에 따라 하위클래스에서 지정하지 않은 메시지에 대해선
상위클래스의 Dispatch()를 호출하여 처리를 위임(?)하는 구조로 되어있습니다.

메시지 맵과 Dispatch()는 사실 직접적인 관계가 있죠.
sysdefs.h를 분석해보시면, 메시지맵 관련 매크로들의 프리프로세서 선언은
다음과 같습니다.

#define BEGIN_MESSAGE_MAP   virtual void __fastcall Dispatch(void *Message) \
         {                                           \
           switch  (((PMessage)Message)->Msg)        \
           {

#define VCL_MESSAGE_HANDLER(msg,type,meth)          \
           case    msg:                              \
             meth(*((type *)Message));               \
             break;

#define END_MESSAGE_MAP(base)           default:    \
      base::Dispatch(Message);    \
                         break;                      \
           }                                         \
         }
프리프로세서 선언만 봐서는 금방 무슨뜻인지 감이 안오실 거 같아서
실제로 예를 들어보면...

BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(WM_CHAR, TWmChar, WmChar)
END_MESSAGE_MAP(TForm)

이와 같은 코드는, 프리프로세싱을 거치고 나면 다음과 같은 코드로 확장됩니다.

virtual void __fastcall Dispatch(void *Message)
{
     switch  (((PMessage)Message)->Msg)
     {
         case WM_CHAR:
         WmChar(*((TWmChar *)WM_CHAR));
         break;

         default:
         TForm::Dispatch(Message);
         break;
     }
}

다시 말하자면, 메시지맵을 작성한다는 자체가, 베이스클래스의 Disaptch()
함수를 오버라이딩 하는 결과가 되는 것입니다.
그리고, 현재의 클래스에서 지정해주지 않은 메시지에 대해서는 default: 레이블을
따라서 베이스클래스의 Dispatch()에 넘겨주게 됩니다.
이런 리커시브한 구조로서, 해당 메시지에 대한 case 문을 찾아 처리가 될때까지
계속 베이스클래스로 내려가면서 핸들링 루틴을 찾게 되는 것입니다. 
vcl에서(아마 다른 윈도우즈 클래스 라이브러리도 거의 비슷한 구조죠)
메시지를 처리하는 방법은 이와같이 대단히 재밌는 구조로 되어있답니다.

그럼 참고하시길...



독립문에서 임펠리테리였습니다.

+ -

관련 글 리스트
3187 [질문] 메세지맵의 문법적의미를 알고 싶습니다. D빌더 3650 2000/03/24
3191     Re:[질문] 메세지맵의 문법적의미를 알고 싶습니다. 박지훈.임프 4257 2000/03/24
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.