홍용혁 님이 쓰신 글 :
: 메세지 맵에서
:
: MESSAGE_HANDLER(메세지,구조체,함수)
:
: 이러한 구조로 되어있는데요.
:
: 만약 어떤 메세지를 다루고 싶을때
:
: "구조체" 에 해당하는것은 어떻게 정하나요..
:
: 어떤책을 보니까 그냥 TMessage 로 하면 된다고 나와있긴한데
:
: 또 다른경우도 봤거든요..
:
: 예를 들어 WM_GETMINMAXINFO 메세지인경우에는
:
: "구조체"를 TWMGetMinMaxInfo 로 하더군요..
:
: 한가지 더 베이스 클래스는 어떻게 정해주나요
임펠리테리입니다.
메시지맵에서 정의하는 메시지 핸들러가 TMessage 형 구조체만 받아야 하는지 여부는 TObject::Dispatch() 함수를 참고하시면 알 수 있습니다. 왜냐하면, 메시지맵을 컴파일러가 해석하는 방법(
Tip'N Tricks 게시판 43번 글 참고))은 결국은 해당 클래스로 들어오는 모든 메시지가 이 메시지맵을 거치도록 하고, 만약 적절한 핸들러가 없을 경우 그 클래스의 Dispatch() 함수를 실행하도록 되어있기 때문입니다. 이 Dispatch() 함수는 원래는 TObject 의 멤버함수이지만 TForm까지 내려오면서 여러 단계에서 오버라이드되어 있으므로 해당 클래스로서 처리해야 하는 모든 메시지를 처리할 능력을 가지고 있습니다.
그런데 이 Dispatch() 함수의 인자를 보면 그냥 void *입니다. 다시 말해서, 어떤 형이든 관계가 없다는 말입니다. 중요한 것은 그 포인터가 가리키는 위치에 정보가, 더블워드 형으로 메시지번호, WParam, LParam, Result 순서로 존재해야 한다는 것입니다. 이 형태는 TMessage의 인자순서와 일치합니다.
VCL을 보면 자주 사용되는 많은 메시지가 전용의 메시지 구조체를 가집니다(여기서 메시지 구조체는 디폴트인 TMessage를 비롯해 TWMGetMinMaxInfo 등의 구조체를 말합니다). 이들 많은 타입의 구조체의 선언을 보면, 약간씩 다르지만, 적어도 16 바이트 길이를 갖는 점은 동일합니다. 그러므로, 여러 메시지에 따라 해석하기 좋도록 제각각의 멤버를 정의한 새로운 구조체를 사용할 수 있습니다. 예를 들면, messages.hpp에 TWMGetMinMaxInfo 구조체는 다음과 같이 선언되어 있습니다.
struct TWMGetMinMaxInfo
{
unsigned Msg;
int Unused;
tagMINMAXINFO *MinMaxInfo;
int Result;
} ;
역시 16바이트 구조로 되어있지요? 여기서 두번째부터의 인자들이 원래 WParam, LParam, Result에 해당하는 것입니다. 다시 말해, TMessage 구조체를 쓰는 것은 일반적이지만, 각 메시지에 따라 그 메시지에 맞는 메시지구조체를 사용하면 사용자가 그 메시지에서 넘어온 WParam, LParam, Result 과 같은 정보들을 직접 해석할 필요가 없어집니다. 다시 말해 편의기능이라고 할 수 있죠.
하지만 모든 메시지가 메시지구조체를 갖는 것은 아닙니다. messages.hpp를 보면 TMessage 를 포함해 약 20여개의 메시지 구조체만 존재합니다. 사용될지 안될지도 모를 아주 가끔씩 사용될 메시지들에 대해 모두 구조체를 만들어줄 수는 없지요? 이런 경우 기본인 TMessage 구조체를 사용하고, 내용은 직접 해석해야 합니다.
그럼 참고하시길...