<b>深化VCL理解BCB的消息机制1</b>[VC/C++编程]
本文“<b>深化VCL理解BCB的消息机制1</b>[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
本文所谈及的技术内容都来自于Internet的公开信息.由CKER在闲暇之际整理后,贴出来以飴网友,姑且妄称原创.
『每次在国外网站上找到精彩文章的时刻,心中城市暗自叹息为什么在中文网站难以觅得这类文章呢?其实缘由大家都懂得.』
时至本日,学习Windows编程的兄弟们都知道消息机制的重要性.所以理解消息机制也成了不可或缺的功课.
大家都知道,Borland的C++ Builder以及Delphi的核心是VCL.作为Win32平台上的开辟工具,封装Windows的消息机制当然也是必不可少的.
那么,在C++ Builder中处理消息的办法有哪些呢?它们之间的辨别又在那边?假如您很清楚这些,呵呵,对不起啦,请关掉这个窗口.
假如不清楚那就和我一同深化VCL的源码看个毕竟吧.『注:BCB只有Professional和Enterprise版本才带有VCL源码.当然,大伙的版本都有源码的.我没猜错吧 :-)<CKER用的是BCB5>』
办法1.利用消息映射(Message Map)重载TObject的Dispatch虚成员函数
这个办法大家用的很多.情势以下
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER( … …)
END_MESSAGE_MAP( …)
但这几句话实在太突兀,C++尺度中没有这样的定义.不用讲,这明显又是宏定义.它们到底怎么来的呢?CKER第一次见到它们的时刻,百思不得其解.嘿嘿,不深化VCL,怎么大概理解?
在\Borland\CBuilder5\Include\Vcl找到sysmac.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;
// NOTE: ATL defines a MESSAGE_HANDLER macro which conflicts with VCL's macro. The
// VCL macro has been renamed to VCL_MESSAGE_HANDLER. If you are not using ATL,
// MESSAGE_HANDLER is defined as in previous versions of BCB.
file://
#if !defined(USING_ATL) && !defined(USING_ATLVCL) && !defined(INC_ATL_HEADERS)
#define MESSAGE_HANDLER VCL_MESSAGE_HANDLER
#endif // ATL_COMPAT
#define END_MESSAGE_MAP(base)
default: \
base::Dispatch(Message); \
break; \
} \
}
这样对以下的例子:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_PAINT,TMessage,OnPaint)
END_MESSAGE_MAP(TForm1)
在预编译时,就被展开成以下的代码
virtual void __fastcall Dispatch(void *Message)
{
switch (((PMessage)Message)->Msg)
{
case WM_PAINT:
OnPaint(*((TMessage *)Message)); //消息呼应句柄,也就是呼应消息的成员函数,在Form1中定义
break;
default:
Form1::Dispatch(Message);
break;
}
}
这样就很顺眼了,对吧.对这种办法有两点要注释一下:
1.virtual void __fastcall Dispatch(void *Message) 这个虚办法的定义最早可以在TObject的定义中找到.翻开
BCB的帮忙,查找TForm的Method(办法),你会发现这里很清楚的写着Dispatch办法担当自TObject.假如您关心VCL的担当机制的话,您会发现TObject是全部VCL对象的基类.TObject的抽象凝集了Borland的工程师们的心血.假若有爱好.您应当好好查看一下TObject的定义.
很明显,全部Tobject的子类都可以重载基类的Dispatch办法,来实现自己的消息调用.假如Dispatch办法找不到此消息的定义,会将此消息交由TObject::DefaultHandler办法来处理.抽象基类TObject的DefaultHandler办法实际上是空的.一样要由担当子类重载实现它们自己的消息处理历程.
2.很多时刻,我见到的第二行是这样写的:
MESSAGE_HANDLER(WM_PAINT,TMessage,OnPaint)
在这里,您可以很清楚的看到几行注解,意思是ATL中一样包含了一个MESSAGE_HANDLER的宏定义,这与VCL发生了冲突.为了办理这个问题,Borland改用VCL_MESSAGE_HANDLER这样的写法.
当您没有利用ATL的时刻,MESSAGE_HANDLER将转换成VCL_MESSAGE_HANDLER.但假如您利用了ATL的话,就会有问题.所以我倡议您始终利用VCL_MESSAGE_HANDLER的写法,免得呈现问题.
以上是“<b>深化VCL理解BCB的消息机制1</b>[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |