Deep VCL understanding of BCB message mechanism 1

Source: Internet
Author: User
Tags inheritance

The technical content discussed in this article comes from public information on the Internet. By Cker in the leisure time after finishing, posted out to 飴 netizens, the original in vain.

"Every time I find a wonderful article on a foreign website, I will sigh in my heart why it is difficult to get such articles in Chinese websites?" In fact, we all know why. 』

Today, the brothers who learn about Windows programming know the importance of the message mechanism. So understanding the message mechanism has also become an indispensable lesson.

As we all know, Borland C + + Builder and the core of Delphi is VCL. As a development tool on the WIN32 platform, the message mechanism for encapsulating Windows is certainly essential.

So what are the ways to process messages in C + + Builder? What is the difference between them? If you are very clear about these, oh, sorry, please turn off this window.

If not clear then and I go deep into the VCL source to see what it is. "Note: BCB only Professional and Enterprise version only with VCL source code." Of course, everyone's version has the source code. I'm not mistaken,:-) <cker is using bcb5>. "

Method 1. Using message map to overload TObject Dispatch virtual member functions

This method is used by a lot of people. form is as follows

BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER( … …)
END_MESSAGE_MAP( …)

But these words are too abrupt, the C + + standard does not have such a definition. Needless to say, this is clearly another macro definition. How the hell did they get here? Cker the first time they saw them, they were baffled. Hey, not deep vcl, how can you understand?

Find sysmac.h in \BORLAND\CBUILDER5\INCLUDE\VCL, which has the following precompiled macro definition:

#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; \
       } \
     }

This is the case for the following:

BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_PAINT,TMessage,OnPaint)
END_MESSAGE_MAP(TForm1)

When precompiled, it is expanded into the following code

virtual void __fastcall Dispatch(void *Message)
{
    switch (((PMessage)Message)->Msg)
    {
     case WM_PAINT:
         OnPaint(*((TMessage *)Message)); //消息响应句柄,也就是响应消息的成员函数,在Form1中定义
     break;
     default:
         Form1::Dispatch(Message);
     break;
    }
}

This is very pleasing to the eye, right. There are two points to explain about this approach:

1. virtual void __fastcall Dispatch (void *message) is the first definition of a virtual method that can be found in the definition of tobject. Open it

BCB help to find the Tform method, you will find it very clear that the dispatch method inherits from TObject. If you are concerned about the inheritance mechanism of VCL, you will find that TObject is the base class for all VCL objects. TObject's abstraction condensed the painstaking efforts of the Borland engineers. If you are interested. You should take a good look at the definition of TObject.

It is clear that all tobject subclasses can overload the dispatch method of the base class to implement their own message invocation. If the dispatch method cannot find the definition of this message, it is handled by the TObject::D Efaulthandler method. The DefaultHandler method of the abstract base class TObject is actually empty. It is also up to the inheritance subclass overload to implement their own message handling process.

2. Most of the time, the second line I saw was written like this:

Message_handler (Wm_paint,tmessage,onpaint)

Here, you can clearly see a few lines of annotations, meaning that ATL also contains a Message_handler macro definition that conflicts with VCL. To solve this problem, Borland switched to Vcl_message_handler.

When you do not use ATL, Message_handler is converted to Vcl_message_handler. But if you use ATL, there's a problem. So I suggest you always use Vcl_message_handler to avoid problems.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.