Question and Answer Database FAQ2369C.txt Writing a VCL component in C++ which defines its own events Category :VCL Platform :All Product :C++Builder 3.x Question: I have scoured the Borland BCB docs and the net and I really haven't found a good example of writing a VCL component in C++ which defines its own events (an event not overriding any ancestor class events). I saw a brief reference to the "_closure" BCB extension in the "Teach Yourself" book that came with 3.0, but that's it. Answer: There's a standard structure which is illustrated in this example: class TXXButton : public TButton { private: TNotifyEvent FOnMouseEnter; // [A] TNotifyEvent FOnMouseLeave; protected: void __fastcall CMMouseEnter(TMessage &Message); // [B] void __fastcall CMMouseLeave(TMessage &Message); BEGIN_MESSAGE_MAP MESSAGE_HANDLER(CM_MOUSEENTER, TMessage, CMMouseEnter) // [C] MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMMouseLeave) END_MESSAGE_MAP(TButton) public: __fastcall TXXButton(TComponent* Owner); __published: __property TNotifyEvent OnMouseEnter = {read=FOnMouseEnter, write=FOnMouseEnter}; // [D] __property TNotifyEvent OnMouseLeave = {read=FOnMouseLeave, write=FOnMouseLeave}; }; void __fastcall TXXButton::CMMouseEnter(TMessage &Message) { if (FOnMouseEnter != NULL) FOnMouseEnter(this); // [E] } void __fastcall TXXButton::CMMouseLeave(TMessage &Message) { if (FOnMouseLeave != NULL) FOnMouseLeave(this); } // ----- end of code ----------- [A] - Will point to the user's event handler if one exists. This is private; the user accesses it via the published property OnMouseEnter - see [D]. [B] - Declaration of your message handler. [C] - This macro basically says 'if CM_MOUSEENTER is received, send it to my function CMMouseEnter' [D] - Because this is published it will appear in the object inspector, and because it's a pointer to a member function it will be listed as an event. You can see that this is just the same as any other published property, the data just happens to be a function pointer. [E] - The most important bit - when the message is received, check whether the user has attached an event handler and if so, call it. If not perform any default action - in this case there is none. I'd suggest you try this for yourself - create a new component derived from TButton and patch in the above. Install the component and play around with it. Try adding some sort of default behaviour by adding code to CMMouseEnter(). Double click the event in the object inspector and add an event handler. Etc. etc. The best source of further info is the VCL source, there's loads of event handling code. 7/2/98 10:32:32 AM
Article originally contributed by Alan Ellis