ActiveX Events in FoxPro

ActiveX components and controls are used in many programming languages, each of which has it’s own way of handling event callbacks.  This blog post provides helpful hints about how to receive event callbacks from an ActiveX component.

To receive the event, you must bind the ActiveX (also referred to as the COM server) event to the implemented interface methods on a Visual FoxPro object.   This is done using FoxPro’s EVENTHANDLER function.  For example:

* oCtrl will be the object in Visual FoxPro to receive the event notifications.
* It will implement one or more of the ActiveX's event callback methods
oCtrl = CREATEOBJECT("Ctrl")

* Create an instance of an ActiveX component:
loMailman = CreateObject('Chilkat.MailMan2')

*The EVENTHANDLER tells the COM object to send events to the VFP object:

Let’s look at the VFP object’s class (i.e. oCtrl):

*Definition of control class:

*The IMPLEMENTS... line below is what makes Foxpro take control over the SendPercentDone,
ReadPercentDone and AbortCheck
*NOTE - This path part of the IMPLEMENTS must point to the dll, so locate and correct it
before you are using the program.
IMPLEMENTS _IChilkatMailEvents IN "c:\mydlls\chilkatmail_v7_9.dll"


PROCEDURE _IChilkatMailEvents_SendPercentDone(percentDone AS Number, abort AS Number) AS VOID;
    HELPSTRING "method SendPercentDone"
    * add user code here


PROCEDURE _IChilkatMailEvents_ReadPercentDone(percentDone AS Number, abort AS Number) AS VOID;
    HELPSTRING "method ReadPercentDone"
    * add user code here


PROCEDURE _IChilkatMailEvents_AbortCheck(abort AS Number) AS VOID;
    HELPSTRING "method AbortCheck"
    * add user code here


PROCEDURE _IChilkatMailEvents_EmailReceived(subject AS String, fromAddr AS String
    fromName AS String, returnPath AS String, date AS String, uidl AS String, 
    sizeInBytes AS Number) AS VOID;
    HELPSTRING "method EmailReceived"
    * add user code here



This is not enough for events to fire.  You’ll need to take one additional step:  Set the AutoYield property = .T. to allow ActiveX events to fire.

Finally, how do you know what events are available for a given ActiveX?   Unfortunately, Chilkat does not have programming-language specific help for the events.  We can look at the IDL for the events and then understand how to write the FoxPro event interfaces.  For example, here’s the IDL for Chilkat MailMan:

dispinterface _IChilkatMailEvents
[id(1), helpstring("method SendPercentDone")] HRESULT SendPercentDone([in] long percentDone, [out] long *abort);
[id(2), helpstring("method ReadPercentDone")] HRESULT ReadPercentDone([in] long percentDone, [out] long *abort);
[id(3), helpstring("method AbortCheck")] HRESULT AbortCheck([out] long *abort);
[id(4), helpstring("method EmailReceived")] HRESULT EmailReceived([in] BSTR subject, [in] BSTR fromAddr,
    [in] BSTR fromName, [in] BSTR returnPath, [in] BSTR date, [in] BSTR uidl, [in] long sizeInBytes);

A few notes:

  • Notice the “_IChilkatMailEvents” corresponds to the “_IChilkatMailEvents” in the FoxPro code.
  • All event methods will be declared as a PROCEDURE returning VOID (i.e. “AS VOID”)
  • Ignore the HRESULT in the IDL.  It doesn’t apply in FoxPro.
  • In the IDL, BSTR means “string”.
  • In the IDL, input arguments are specified by “[in]”, output arguments are specified by “[out]”.  A common output argument is “abort”.  Your event handler may set it equal to 1 to abort the current Chilkat method that is running, or leave it at 0 to allow it to continue.

That’s about it.   You should be able to look at the IDL and know how to create your event handling code in FoxPro.  Here’s a link to the IDL for SFtp, Zip, MailMan, Ftp2, HTTP, and IMAP: