Writing a VCL component in C++ which defines its own events

by Mar 13, 1998

 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