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
[11070] Re:논리적인 재귀호출을 하셨습니다.
박지훈.임프 [cbuilder] 1170 읽음    2001-09-14 01:41
임프랍니다.

예전에도 한번 답변을 한 거 같은데, 찾아보기가 귀찮아서.. (질문자보다 더 게으른 답변자... -.-;;)

결론부터 말씀드리면, 헤더파일 내에서 메시지맵을 구성한 마지막 라인, 즉 END_MESSAGE_MAP(TFrmMain)을
END_MESSAGE_MAP(TForm)으로 바꾸어줘야 합니다.

이유는... 일단 다음의 팁을 먼저 보세요.
http://www.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=43

간단히 위 팁의 내용을 요약해서 말씀드리면.. 메시지맵을 구성하는 세개의 문장은 실제로는 매크로입니다.
이 매크로들이 차례로 해석되고 나면, END_MESSAGE_MAP(TForm) 은 다음의 라인을 실행하는 것으로
치환됩니다.
TForm::Dispatch(Message);

Dispatch() 함수는 소속 클래스내로 들어오는 메시지를 처리하는 함수입니다. 이 함수에서 각 메시지핸들러
들에게 메시지를 분배합니다. 결과적으로, 상위 클래스, 즉 TForm의 메시지 처리 루틴을 호출하는 겁니다.

그런데 여기다가 TForm 대신 TFrmMain을 넣어줬으니, 상위클래스가 아닌 자신 클래스의 Dispatch()를 호출
한 거고, 이 자신 클래스의 Dispatch()는 다시 각 메시지별로 핸들러를 호출하는데요. 그럼 메시지핸들러에
등록해놓은 최초의 핸들러가 다시 호출됩니다.

결론적으로 말하면, 메시지핸들러가 다시 자신을 호출하게 되는 거지요. 논리적인 재귀호출입니다.
종료시점이 없으니 무한반복하면서 계속 재귀호출을 하므로 아무리 스택이 많아도 결국 스택오버플로우가
발생하게 됩니다.

메시지처리에 대해 아직 아리송하다면 위의 팁을 다시 자세히 읽어보시기 바랍니다.
그럼 이만...


헐~ 님이 쓰신 글 :
: 윈도우 메세지를 받는 부분을 구현해야 되는데,
: WndProc 를 오버라이딩 하는 방법이나, 메시지 맵을 이용하는 방법을 모두 사용해 봤는데, 잘 안되더라고요.
: 컴파일은 잘 되는데, 실행시에 스텍오버플로라는 에러 메시지가 뜹니다..
: 일단 헤더에 다음과 같이 디파인해 주었고,
: #define WM_CLIENT_MSG WM_USER+8
:
: private:    // User declarations
:         void __fastcall WMSysCommand(TMessage &Message);
:
: protected:
:         BEGIN_MESSAGE_MAP        // 메시지 맵을 선언
:                 MESSAGE_HANDLER(WM_CLIENT_MSG,TMessage,WMSysCommand)
:         END_MESSAGE_MAP(TFrmMain)
:
: Cpp화일에는
:
: void __fastcall TFrmMain::WMSysCommand(TMessage &Message)
: {
:         if(Message.CmdType == WM_CLIENT_MSG)
:                if(Message.WParam == 4)
:                 {
:                         if(Message.LParam == 1)
:                         {
:                                 Application->MessageBox("사용자 메시지 테스트->접속성공","경고",MB_OK);
:                         }
:                         else
:                         {
:                                 Application->MessageBox("사용자 메시지 테스트->접속실패","경고",MB_OK) ;
:                         }
:
:                 }
:                 else
:                         TFrmMain::Dispatch(&Message);
:
: }
:
: 에러가 뜨는 이유를 가르쳐 주세요.
: 부탁합니다.

+ -

관련 글 리스트
11011 메시지 맵에서......(고수님들 부탁합니다.) 헐~ 1041 2001/09/13
11070     Re:논리적인 재귀호출을 하셨습니다. 박지훈.임프 1170 2001/09/14
11013     Re:메시지 맵에서......(고수님들 부탁합니다.) 최상천 1181 2001/09/13
11021         Re:Re:메시지 맵에서......(고수님들 부탁합니다.)...다시한번 부탁합니다 헐~ 1228 2001/09/13
11026             Re:Re:Re:메시지 맵에서......(고수님들 부탁합니다.)...다시한번 부탁합니다 박세호 1167 2001/09/13
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.