ActiveX Controls: Adding Custom Events to an ActiveX Control

OverviewHow Do IFAQSample

Custom events differ from stock events in that they are not automatically fired by class COleControl. A custom event recognizes a certain action, determined by the control developer, as an event. The event map entries for custom events are represented by the EVENT_CUSTOM macro. The following section implements a custom event for an ActiveX control project that was created using ControlWizard.

Adding a Custom Event with ClassWizard

The following procedure adds a specific custom event, ClickIn. You can use this procedure to add other custom events. Simply substitute your custom event name and its parameters for the ClickIn event name and parameters.

To add the ClickIn custom event using ClassWizard

  1. Load your control’s project.

  2. On the View menu, click ClassWizard.

  3. Click the ActiveX Events tab.

  4. Select the name of the control class from the Class name box.

  5. Click Add Event.

  6. In the External name box, type ClickIn.

  7. In the Internal name box, type the name of the event’s firing function. For this example, use the default value provided by ClassWizard (FireClickIn).

  8. Add a parameter, called xCoord (type OLE_XPOS_PIXELS), using the Parameter List grid control.

  9. Add a second parameter, called yCoord (type OLE_YPOS_PIXELS), using the Parameter List grid control.

  10. Click OK to close Add Event.

  11. Click OK again to confirm your choices and close ClassWizard.

ClassWizard Changes for Custom Events

When you add a custom event, ClassWizard makes changes to the control class .H, .CPP, and .ODL files. The following code samples are specific to the ClickIn event.

The following lines are added to the header (.H) file of your control class:

void FireClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord)
    {FireEvent(eventidClickIn,EVENT_PARAM(VTS_XPOS_PIXELS  VTS_YPOS_PIXELS), xCoord, yCoord);}

This code declares an inline function called FireClickIn that calls with the ClickIn event and parameters you defined using ClassWizard.

In addition, the following line is added to the event map for the control, located in the implementation (.CPP) file of your control class:

EVENT_CUSTOM("ClickIn", FireClickIn, VTS_XPOS_PIXELS  VTS_YPOS_PIXELS)

This code maps the event ClickIn to the inline function FireClickIn, passing the parameters you defined using ClassWizard.

Finally, the following line is added to your control’s .ODL file:

[id(1)] void ClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord);

This line assigns the ClickIn event a specific ID number, taken from the event’s position in the ClassWizard event list. The entry in the event list allows a container to anticipate the event. For example, it might provide handler code to be executed when the event is fired.

Calling FireClickIn

Now that you have added the ClickIn custom event using ClassWizard, you must decide when this event is to be fired. You do this by calling FireClickIn when the appropriate action occurs. For this discussion, the control uses the InCircle function inside a WM_LBUTTONDOWN message handler to fire the ClickIn event when a user clicks inside a circular or elliptical region. The following procedure adds the WM_LBUTTONDOWN handler.

To add a message handler with ClassWizard

  1. Load your control’s project.

  2. On the View menu, click ClassWizard.

  3. Click the Message Maps tab.

  4. In the Object IDs box, select the control class name, in this case, CSampleCtrl.

  5. In the Messages box, select the message you would like to handle. For this example, select WM_LBUTTONDOWN.

  6. Click Add Function to add the handler function to your application.

  7. Click Edit Code to jump to the location of the message handler, or click OK to confirm your choice.

The following code sample calls the InCircle function every time the left mouse button is clicked within the control window. This sample can be found in the WM_LBUTTONDOWN handler function, OnLButtonDown, in the Circle sample described in Tutorials. For more information on this function, see , also in Tutorials.

void CSampleCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
    if (InCircle(point))
        FireClickIn(point.x, point.y);

    COleControl::OnLButtonDown(nFlags, point);
}

Note   When ClassWizard creates message handlers for mouse button actions, a call to the same message handler of the base class is automatically added. Do not remove this call. If your control uses any of the stock mouse messages, the message handlers in the base class must be called to ensure that mouse capture is handled properly.

In the following example, the event fires only when the click occurs inside a circular or elliptical region within the control. To achieve this behavior, you can place the InCircle function, taken from of Tutorials, in your control’s implementation (.CPP) file:

BOOL CSampleCtrl::InCircle(CPoint& point)
{
    CRect rc;
    GetClientRect(rc);
    // Determine radii
    double a = (rc.right - rc.left) / 2;
    double b = (rc.bottom - rc.top) / 2;
   
    // Determine x, y
    double x = point.x - (rc.left + rc.right) / 2;
    double y = point.y - (rc.top + rc.bottom) / 2;
   
    // Apply ellipse formula
    return ((x * x) / (a * a) + (y * y) / (b * b) <= 1);
}

You will also need to add the following declaration of the InCircle function to your control’s header (.H) file:

BOOL InCircle( CPoint& point );

Custom Events with Stock Names

You can create custom events with the same name as stock events, however you can not implement both in the same control. For example, you might want to create a custom event called Click that does not fire when the stock event Click would normally fire. You could then fire the Click event at any time by calling its firing function.

The following procedure adds a custom Click event.

To add a custom event that uses a stock event name

  1. Load your control’s project.

  2. On the View menu, click ClassWizard.

  3. Click the ActiveX Events tab.

  4. Click Add Event.

  5. In the External name box, select a stock event name. For this example, select Click.

  6. In the Implementation box, click Custom.

  7. Click OK.

  8. Click OK again to confirm your choices and exit ClassWizard.

  9. Call FireClick at appropriate places in your code.

See Also   ActiveX Controls: Methods,