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

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[43] 팁! 메시지가 vcl에서 처리되는 방법
박지훈.임프 [cbuilder] 20137 읽음    1999-06-04 00:00
임프랍니다..
오늘은, 에고~ 걱정했던대로 또 버그가 발견되는 바람에, 조금 바쁘답니다.
그런디.. 팁거리(국거리??)를 생각해보려고 해도, 마땅히 생각나는 것도 없고..
그래서 며칠전.. 어젠가.. 그저껜가.. 비파툴에 올렸던 답변 내용을 일단
긁어다 놓고, 조금 더 부연설명하려는 식으로.. 나가봅시다.

제  목:[질문]Dispatch() 함수에 관하여....
보낸이:권대길  (한꼬맹이)    1999-01-03 23:37  조회:6  1/1
───────────────────────────────────────
Dispatch() 함수가 뭘 하는지 자세히 알고 싶습니다.
제 생각에는 메세지 맵에서 무슨일을 하고 있다는 것 정도
감 잡았다고나 할까.....
이 함수가 어떻게 작용을 하는지 그리고 어떨때 오버라이딩해서
쓰는지 알고 싶습니다.
알고 계시는 분 께서는 답변해 주시면 감사하겠습니다.
참고로 21번 비파툴을 이용합시다 란에 C++ Builder 강좌란
계설에 대한 제 의견을 적어 놓아습니다....
저 와 의견이 같으신 분은 우리 시삽님에게 편지 한통만
꼭 보내 주세요..
그렇게 해야 Builder 강좌란이 빨리 생기게 되거든요...
늦었지만 비파툴 가족 여러분 새해복 많이 받으세요..

한꼬맹이




━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
제  목:[답변] Dispatch() 함수에 관하여....
보낸이:박지훈  (cbuilder)    1999-01-04 15:46  조회:19  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  (Message->Msg)
   {
       case WM_CHAR:
       WmChar(*((TWmChar *)WM_CHAR));
       break;

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


다시 말하자면, 메시지맵을 작성한다는 자체가, 베이스클래스의 Disaptch() 함수를 오버라이딩 하는 결과가 되는 것입니다. 그리고, 현재의 클래스에서 지정해주지 않은 메시지에 대해서는 default: 레이블을 따라서 베이스클래스의 Dispatch()에 넘겨주게 됩니다.

이런 리커시브한 구조로서, 해당 메시지에 대한 case 문을 찾아 처리가 될때까지 계속 베이스클래스로 내려가면서 핸들링 루틴을 찾게 되는 것입니다. vcl에서(아마 다른 윈도우즈 클래스 라이브러리도 거의 비슷한 구조죠) 메시지를 처리하는 방법은 이와같이 대단히 재밌는 구조로 되어있답니다.

그럼 참고하시길...


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



-----------------------------------------------------------------------------

위에서, WndProc() 함수가, 마지막엔 Dispatch() 함수를 호출하게 된다고 했는데..
정확히 어느 소스였는지는 기억나지 않지만, vcl 소스를 뒤져서 WndProc 함수의 바디를 찾아보면, 실제로 별도로 처리할 몇개의 메시지만 case문으로 처리한 후, 나머지는 몽땅 베이스클래스의 Dispatch() 함수에게 떠맡겨버리는 걸 볼 수 있습니다.

메시지맵은, 빌더 뿐 아니라, 이전 버전인 볼랜드씨에서도 사용했고, 경쟁툴인 비주얼씨에서 아직도 모든 메시지처리의 방법으로 사용하고 있습니다. (비주얼씨의 메시지맵은 정의가 좀 다릅니다.)

그럼, 참고하세요.
에구.. 요즘은 재밌고 쇼킹한 팁거리가 떨어져서.. 쩝...
제보 주세요, 제보~ ^^;;;;




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

+ -

관련 글 리스트
43 팁! 메시지가 vcl에서 처리되는 방법 박지훈.임프 20137 1999/06/04
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.