当前位置:七道奇文章资讯编程技术VC/C++编程
日期:2011-03-22 13:55:00  来源:本站整理

<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++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • <b>hosts是什么 hosts文件在什么位置 若何改正hosts</b>
  • <b>在 Windows 8 中手动安装语言包</b>
  • <b>五个常见 PHP数据库问题</b>
  • Windows中Alt键的12个高效快速的利用本领介绍
  • <b>MySQL ORDER BY 的实现解析</b>
  • <b>详解MySQL存储历程参数有三种范例(in、out、inout)</b>
  • <b>Win8系统恢复出来经典的开始菜单的办法</b>
  • <b>Win8系统花屏怎么办 Win8系统花屏的办理办法</b>
  • <b>Windows 7系统下无线网卡安装</b>
  • <b>为什么 Linux不需求碎片整理</b>
  • <b>Windows 8中删除账户的几种办法(图)</b>
  • <b>教你如安在win7下配置路由器</b>
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .