Export (0) Print
Expand All

Step 5: Adding an Event

In this step, you will add a ClickIn and a ClickOut event to your ATL control. You will fire the ClickIn event if the user clicks inside the polygon and fire ClickOut if the user clicks outside. The tasks to add an event are as follows:

  • Adding the ClickIn and ClickOut Methods

  • Generating the Type Library

  • Implementing the Connection Point Interfaces

When you created the ATL control in step 2, you selected the Connection points check box. This created the _IPolyCtlEvents interface in the Polygon.idl file. Notice that the interface name starts with an underscore (_). This is a convention to indicate that the interface is an internal interface so that programs that allow COM objects to be browsed can be set not to display the interface to the user. Also notice that selecting Connection points added the following line in the Polygon.idl file to indicate that _IPolyCtlEvents is the default source interface.

[default, source] dispinterface _IPolyCtlEvents;

The source attribute indicates that the control is the source of the notifications; the container (in this case, Internet Explorer) implements this interface to receive the notifications.

Now add the ClickIn and ClickOut methods to the _IPolyCtlEvents interface.

To add the ClickIn and ClickOut methods

  1. In Class View, expand Polygon and PolygonLib to display _IPolyCtlEvents.

  2. Right-click _IPolyCtlEvents. On the shortcut menu, click Add, and then click Add Method.

  3. Select a Return Type of void.

  4. Type ClickIn in the Method name box.

  5. Under Parameter attributes, select the in box.

  6. Select a Parameter type of LONG.

  7. Type x as the Parameter name, and click Add.

  8. Repeat steps 5 through 7, this time for a Parameter name of y.

  9. Click Finish.

  10. Repeat the steps above to define a ClickOut method that has the same LONG parameters x and y, the same Parameter attributes and the same void return type.

Check the Polygon.idl file to see that the code was added to the _IPolyCtlEvents dispinterface.

The _IPolyCtlEvents dispinterface in your Polygon.idl file should now resemble this code:

dispinterface _IPolyCtlEvents
{
   properties:
   methods:
      [id(1), helpstring("method ClickIn")] void ClickIn([in] LONG x, [in] LONG y);
      [id(2), helpstring("method ClickOut")] void ClickOut([in] LONG x, [in] LONG y);
};

The ClickIn and ClickOut methods take the x and y coordinates of the clicked point as parameters.

Generate the type library at this point, because the Connection Point Wizard will use it to obtain the information it requires to construct a connection-point interface and a connection-point container interface for your control.

To generate the type library

  • Right-click the Polygon.idl file in Solution Explorer and then click Compile.

This will create the Polygon.tlb file, which is your type library. The Polygon.tlb file is not displayed in Solution Explorer, because it is a binary file and cannot be modified directly.

Implement a connection-point interface and a connection-point container interface for your control. In COM, events are implemented through the mechanism of connection points. To receive events from a COM object, a container establishes an advisory connection to the connection point that the COM object implements. Because a COM object can have multiple connection points, the COM object also implements a connection-point container interface. Through this interface, the container can determine which connection points are supported.

The interface that implements a connection point is named IConnectionPoint, and the interface that implements a connection-point container is named IConnectionPointContainer.

To help implement IConnectionPoint, you will use the Implement Connection Point Wizard. This wizard generates the IConnectionPoint interface by reading your type library and implementing a function for each event that can be fired.

To use the Implement Connection Point Wizard

  1. In Class View, right-click your control's implementation class, CPolyCtl, click Add, and then click Add Connection Point.

  2. Select _IPolyCtlEvents from the Source Interfaces list and double-click it to add it to the Implement connection points column. Click Finish. A proxy class for the connection point will be generated; in this case, it is CProxy_IPolyCtlEvents.

When look at the generated _IPolyCtlEvents_CP.h file in Solution Explorer, notice that it has a class named CProxy_IPolyCtlEvents that derives from IConnectionPointImpl. _IPolyCtlEvents_CP.h also defines the two methods, Fire_ClickIn and Fire_ClickOut, that take the two coordinate parameters. You call these methods when you want to fire an event from your control.

The wizard also added CProxy_PolyEvents and IConnectionPointContainerImpl to your control's multiple inheritance list. The wizard also exposed IConnectionPointContainer by adding appropriate entries to the COM map.

You are finished implementing the code to support events. Now, add some code to fire the events at the appropriate moment. Remember, you are going to fire a ClickIn or ClickOut event when the user clicks the left mouse button in the control. To find out when the user clicks the button, add a handler for the WM_LBUTTONDOWN message.

To add a handler for the WM_LBUTTONDOWN message

  1. In Class View, right-click the CPolyCtl class and then click Properties.

  2. In the Properties window, click the Messages icon and then click WM_LBUTTONDOWN from the list on the left.

  3. On the drop-down list that appears, click <Add> OnLButtonDown. The OnLButtonDown handler declaration will be added to PolyCtl.h, and the handler implementation will be added to PolyCtl.cpp.

Next, modify the handler.

To modify the OnLButtonDown method

  • Change the code in the OnLButtonDown method in PolyCtl.cpp (deleting any code placed by the wizard) so that it resembles this code:

    LRESULT CPolyCtl::OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, 
       BOOL& /*bHandled*/)
    {
       HRGN hRgn;
       WORD xPos = LOWORD(lParam);  // horizontal position of cursor
       WORD yPos = HIWORD(lParam);  // vertical position of cursor
    
       CalcPoints(m_rcPos);
    
       // Create a region from our list of points
       hRgn = CreatePolygonRgn(&m_arrPoint[0], m_nSides, WINDING);
    
       // If the clicked point is in our polygon then fire the ClickIn 
       //  event otherwise we fire the ClickOut event 
       if (PtInRegion(hRgn, xPos, yPos))
          Fire_ClickIn(xPos, yPos);
       else
          Fire_ClickOut(xPos, yPos);
    
       // Delete the region that we created
       DeleteObject(hRgn);
       return 0;
    }
    

This code makes use of the points calculated in the OnDraw function to create a region that detects the user's mouse clicks with the call to PtInRegion.

The uMsg parameter is the ID of the Windows message that is being handled. This makes it possible to have one function that handles a range of messages. The wParam and the lParam parameters are the standard values for the message being handled. By using the bHandled parameter, you can specify whether the function handled the message or not. By default, the value is set to TRUE to indicate that the function handled the message, but you can set it to FALSE. This will cause ATL to continue looking for another message-handler function to send the message to.

Now try out your events. Build the control and start the ActiveX Control Test Container again. This time, view the event log window. To route events to the output window, click Logging on the Options menu and select Log to output window. Insert the control and try clicking in the window. Notice that ClickIn is fired when you click inside of the filled polygon, and ClickOut is fired when you click outside of it.

Next, you will add a property page.

Back to Step 4 | On to Step 6

Community Additions

ADD
Show:
© 2014 Microsoft