Figure 1   A Full Control


 class ATL_NO_VTABLE CFullATLControl : 
     public CComObjectRootEx<CComSingleThreadModel>,
     public IDispatchImpl<IFullATLControl, 
                         &IID_IFullATLControl, &LIBID_ALLCTLSLib>,
     public CComControl<CFullATLControl>,
     public IPersistStreamInitImpl<CFullATLControl>,
     public IOleControlImpl<CFullATLControl>,
     public IOleObjectImpl<CFullATLControl>,
     public IOleInPlaceActiveObjectImpl<CFullATLControl>,
     public IViewObjectExImpl<CFullATLControl>,
     public IOleInPlaceObjectWindowlessImpl<CFullATLControl>,
     public IPersistStorageImpl<CFullATLControl>,
     public ISpecifyPropertyPagesImpl<CFullATLControl>,
     public IQuickActivateImpl<CFullATLControl>,
     public IDataObjectImpl<CFullATLControl>,
     public IProvideClassInfo2Impl<&CLSID_FullATLControl, 
                                    NULL, &LIBID_ALLCTLSLib>,
     public CComCoClass<CFullATLControl, &CLSID_FullATLControl>
 {
     .
     .
     .
BEGIN_COM_MAP(CFullATLControl)
     COM_INTERFACE_ENTRY(IFullATLControl)
     COM_INTERFACE_ENTRY(IDispatch)
     COM_INTERFACE_ENTRY(IViewObjectEx)
     COM_INTERFACE_ENTRY(IViewObject2)
     COM_INTERFACE_ENTRY(IViewObject)
     COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
     COM_INTERFACE_ENTRY(IOleInPlaceObject)
     COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
     COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
     COM_INTERFACE_ENTRY(IOleControl)
     COM_INTERFACE_ENTRY(IOleObject)
     COM_INTERFACE_ENTRY(IPersistStreamInit)
     COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
     COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
     COM_INTERFACE_ENTRY(IQuickActivate)
     COM_INTERFACE_ENTRY(IPersistStorage)
     COM_INTERFACE_ENTRY(IDataObject)
     COM_INTERFACE_ENTRY(IProvideClassInfo)
     COM_INTERFACE_ENTRY(IProvideClassInfo2)
 END_COM_MAP()
     .
     .
     .
};

Figure 2   A Lite Control

 
 class ATL_NO_VTABLE CLiteATLControl : 
     public CComObjectRootEx<CComSingleThreadModel>,
     public IDispatchImpl<ILiteATLControl, 
                         &IID_ILiteATLControl, &LIBID_ALLCTLSLib>,
     public CComControl<CLiteATLControl>,
     public IPersistStreamInitImpl<CLiteATLControl>,
     public IOleControlImpl<CLiteATLControl>,
     public IOleObjectImpl<CLiteATLControl>,
     public IOleInPlaceActiveObjectImpl<CLiteATLControl>,
     public IViewObjectExImpl<CLiteATLControl>,
     public IOleInPlaceObjectWindowlessImpl<CLiteATLControl>,
     public CComCoClass<CLiteATLControl, &CLSID_LiteATLControl>
 {
     .
     .
     .
BEGIN_COM_MAP(CLiteATLControl)
     COM_INTERFACE_ENTRY(ILiteATLControl)
     COM_INTERFACE_ENTRY(IDispatch)
     COM_INTERFACE_ENTRY(IViewObjectEx)
     COM_INTERFACE_ENTRY(IViewObject2)
     COM_INTERFACE_ENTRY(IViewObject)
     COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
     COM_INTERFACE_ENTRY(IOleInPlaceObject)
     COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
     COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
     COM_INTERFACE_ENTRY(IOleControl)
     COM_INTERFACE_ENTRY(IOleObject)
     COM_INTERFACE_ENTRY(IPersistStreamInit)
     COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
 END_COM_MAP()
     .
     .
     .
};

Figure 3   A Full Control Versus a Lite Control

 
     public IPersistStorageImpl<CFullATLControl>,
     public ISpecifyPropertyPagesImpl<CFullATLControl>,
     public IQuickActivateImpl<CFullATLControl>,
     public IDataObjectImpl<CFullATLControl>,
     public IProvideClassInfo2Impl<&CLSID_FullATLControl, 
                                   NULL, &LIBID_ALLCTLSLib>,
     .
     .
     .
BEGIN_COM_MAP(…)
     COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
     COM_INTERFACE_ENTRY(IQuickActivate)
     COM_INTERFACE_ENTRY(IPersistStorage)
     COM_INTERFACE_ENTRY(IDataObject)
     COM_INTERFACE_ENTRY(IProvideClassInfo)
     COM_INTERFACE_ENTRY(IProvideClassInfo2)
 END_COM_MAP()

Figure 4   A Composite Control

 
 class ATL_NO_VTABLE CCompositeATLControl : 
     public CComObjectRootEx<CComSingleThreadModel>,
     public IDispatchImpl<ICompositeATLControl, 
                         &IID_ICompositeATLControl,
                         &LIBID_ALLCTLSLib>,
     public CComCompositeControl<CCompositeATLControl>,
     public IPersistStreamInitImpl<CCompositeATLControl>,
     public IOleControlImpl<CCompositeATLControl>,
     public IOleObjectImpl<CCompositeATLControl>,
     public IOleInPlaceActiveObjectImpl<CCompositeATLControl>,
     public IViewObjectExImpl<CCompositeATLControl>,
     public IOleInPlaceObjectWindowlessImpl<CCompositeATLControl>,
     public IPersistStorageImpl<CCompositeATLControl>,
     public ISpecifyPropertyPagesImpl<CCompositeATLControl>,
     public IQuickActivateImpl<CCompositeATLControl>,
     public IDataObjectImpl<CCompositeATLControl>,
     public IProvideClassInfo2Impl<&CLSID_CompositeATLControl, 
                                  NULL, &LIBID_ALLCTLSLib>,
     public CComCoClass<CCompositeATLControl,
                       &CLSID_CompositeATLControl>
 {
 BEGIN_COM_MAP(CCompositeATLControl)
     COM_INTERFACE_ENTRY(ICompositeATLControl)
     COM_INTERFACE_ENTRY(IDispatch)
     COM_INTERFACE_ENTRY(IViewObjectEx)
     COM_INTERFACE_ENTRY(IViewObject2)
     COM_INTERFACE_ENTRY(IViewObject)
     COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
     COM_INTERFACE_ENTRY(IOleInPlaceObject)
     COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
     COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
     COM_INTERFACE_ENTRY(IOleControl)
     COM_INTERFACE_ENTRY(IOleObject)
     COM_INTERFACE_ENTRY(IPersistStreamInit)
     COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
     COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
     COM_INTERFACE_ENTRY(IQuickActivate)
     COM_INTERFACE_ENTRY(IPersistStorage)
     COM_INTERFACE_ENTRY(IDataObject)
     COM_INTERFACE_ENTRY(IProvideClassInfo)
     COM_INTERFACE_ENTRY(IProvideClassInfo2)
 END_COM_MAP()
 };

Figure 5   A Lite Composite Control

 
 class ATL_NO_VTABLE CLiteCompositeATLControl : 
     public CComObjectRootEx<CComSingleThreadModel>,
     public IDispatchImpl<ILiteCompositeATLControl,
                         &IID_ILiteCompositeATLControl,
                         &LIBID_ALLCTLSLib>,
     public CComCompositeControl<CLiteCompositeATLControl>,
     public IPersistStreamInitImpl<CLiteCompositeATLControl>,
     public IOleControlImpl<CLiteCompositeATLControl>,
     public IOleObjectImpl<CLiteCompositeATLControl>,
     public IOleInPlaceActiveObjectImpl<CLiteCompositeATLControl>,
     public IViewObjectExImpl<CLiteCompositeATLControl>,
     public IOleInPlaceObjectWindowlessImpl<CLiteCompositeATLControl>,
     public CComCoClass<CLiteCompositeATLControl,
                       &CLSID_LiteCompositeATLControl>
 {
 BEGIN_COM_MAP(CLiteCompositeATLControl)
     COM_INTERFACE_ENTRY(ILiteCompositeATLControl)
     COM_INTERFACE_ENTRY(IDispatch)
     COM_INTERFACE_ENTRY(IViewObjectEx)
     COM_INTERFACE_ENTRY(IViewObject2)
     COM_INTERFACE_ENTRY(IViewObject)
     COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
     COM_INTERFACE_ENTRY(IOleInPlaceObject)
     COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
     COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
     COM_INTERFACE_ENTRY(IOleControl)
     COM_INTERFACE_ENTRY(IOleObject)
     COM_INTERFACE_ENTRY(IPersistStreamInit)
     COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
 END_COM_MAP()
 };

Figure 6   A Full HTML Control

 
 class ATL_NO_VTABLE CHTMLATLControl : 
     public CComObjectRootEx<CComSingleThreadModel>,
     public IDispatchImpl<IHTMLATLControl, 
                         &IID_IHTMLATLControl, &LIBID_ALLCTLSLib>,
     public IDispatchImpl<IHTMLATLControlUI, 
                          &IID_IHTMLATLControlUI, &LIBID_ALLCTLSLib>,
     public CComControl<CHTMLATLControl>,
     public IPersistStreamInitImpl<CHTMLATLControl>,
     public IOleControlImpl<CHTMLATLControl>,
     public IOleObjectImpl<CHTMLATLControl>,
     public IOleInPlaceActiveObjectImpl<CHTMLATLControl>,
     public IViewObjectExImpl<CHTMLATLControl>,
     public IOleInPlaceObjectWindowlessImpl<CHTMLATLControl>,
     public IPersistStorageImpl<CHTMLATLControl>,
     public ISpecifyPropertyPagesImpl<CHTMLATLControl>,
     public IQuickActivateImpl<CHTMLATLControl>,
     public IDataObjectImpl<CHTMLATLControl>,
     public IProvideClassInfo2Impl<&CLSID_HTMLATLControl, 
                                  NULL, &LIBID_ALLCTLSLib>,
     public CComCoClass<CHTMLATLControl, &CLSID_HTMLATLControl>
 {
 };

Figure 7   A Lite HTML Control

 
 class ATL_NO_VTABLE CLiteHTMLATLControl : 
     public CComObjectRootEx<CComSingleThreadModel>,
     public IDispatchImpl<ILiteHTMLATLControl, 
                         &IID_ILiteHTMLATLControl,
                         &LIBID_ALLCTLSLib>,
     public IDispatchImpl<ILiteHTMLATLControlUI,
                         &IID_ILiteHTMLATLControlUI,
                         &LIBID_ALLCTLSLib>,
     public CComControl<CLiteHTMLATLControl>,
     public IPersistStreamInitImpl<CLiteHTMLATLControl>,
     public IOleControlImpl<CLiteHTMLATLControl>,
     public IOleObjectImpl<CLiteHTMLATLControl>,
     public IOleInPlaceActiveObjectImpl<CLiteHTMLATLControl>,
     public IViewObjectExImpl<CLiteHTMLATLControl>,
     public IOleInPlaceObjectWindowlessImpl<CLiteHTMLATLControl>,
     public CComCoClass<CLiteHTMLATLControl,
                       &CLSID_LiteHTMLATLControl>
 {
 };

Figure 8   The ATLMsgTrafficCtl IDL

 
 interface IATLMsgTrafficCtlEventsCustom;
  [
     object,
     uuid(C30CCA3D-A482-11D2-8038-6425D1000000),
     dual,
     helpstring("IATLMsgTrafficCtl Interface"),
     pointer_default(unique)
 ]
 interface IATLMsgTrafficCtl : IDispatch
 {
     //  method for connecting with the client 
     [id(6), helpstring("method Advise")] 
     HRESULT Advise([in]IATLMsgTrafficCtlEventsCustom*
                    pATLMsgTrafficCtlEventsCustom, 
                    [out]long* pCookie);
     [id(7), helpstring("method Unadvise")] 
     HRESULT Unadvise([in]long lCookie);
 };
 
 [
     uuid(C30CCA31-A482-11D2-8038-6425D1000000),
     version(1.0),
     helpstring("ATLMsgTraffic 1.0 Type Library")
 ]
 library ATLMSGTRAFFICLib
 {
     importlib("stdole32.tlb");
     importlib("stdole2.tlb");
 
     // This is the interface for use with
     //  connection points
     [
         uuid(C30CCA3F-A482-11D2-8038-6425D1000000),
     ]
     dispinterface _IATLMsgTrafficCtlEvents
     {
        properties:
        methods:
            [id(1)] void ExceededThreshold(long NumMessages, 
                                           long CurrentThreshold);
            [id(2)] void NewInterval(long NumMessages);
    };
 
    // This is the custom callback interface 
    [
        uuid(A0481C89-A4D7-11d2-8039-84DD6A000000),
        object,
        oleautomation
    ]
    interface IATLMsgTrafficCtlEventsCustom : IUnknown
    {
        HRESULT ExceededThreshold(long NumMessages, 
                                  long CurrentThreshold);
        HRESULT NewInterval(long NumMessages);
    };
 
    [
        uuid(C30CCA3E-A482-11D2-8038-6425D1000000),
        helpstring("ATLMsgTrafficCtl Class")
    ]
    coclass ATLMsgTrafficCtl
    {
        [default] interface IATLMsgTrafficCtl;
        [default, source] dispinterface _IATLMsgTrafficCtlEvents;
        [source] interface IATLMsgTrafficCtlEventsCustom;
    };
 
    [
        uuid(C30CCA42-A482-11D2-8038-6425D1000000),
        helpstring("MainPropPage Class")
    ]
 };

Figure 10   Using ATLMsgTrafficCtl in the Form

 
 Dim g_cookie As Long
 Implements IATLMsgTrafficCtlEventsCustom
 
 Private Sub Form_Load()
     ATLMsgTrafficCtl1.Advise Me, g_cookie
 End Sub
 
 Private Sub 
 ATLMsgTrafficCtl1_ExceededThreshold(ByVal NumMessages As Long, 
                                     ByVal CurrentThreshold As Long)
     Dim eventStr As String
     
     eventStr = "Exceeded Threshold: " + Str(CurrentThreshold)
     NormalEvents.AddItem eventStr
 End Sub
 
 Private Sub ATLMsgTrafficCtl1_NewInterval(ByVal NumMessages As Long)
     Dim eventStr As String
     
     eventStr = "New Interval" + Str(NumMessages)
     NormalEvents.AddItem eventStr
 End Sub
 
 Private Sub 
 IATLMsgTrafficCtlEventsCustom_ExceededThreshold(
     ByVal NumMessages As Long, 
     ByVal CurrentThreshold As Long)
     Dim eventStr As String
     
     eventStr = "Exceeded Threshold: " + Str(CurrentThreshold)
     CustomEvents.AddItem eventStr
 End Sub
 
 Private Sub 
 IATLMsgTrafficCtlEventsCustom_NewInterval(ByVal NumMessages As Long)
     Dim eventStr As String
     
     eventStr = "New Interval: " + Str(NumMessages)
     CustomEvents.AddItem eventStr
 End Sub
 
 Private Sub Start_Click()
     ATLMsgTrafficCtl1.StartGraph
 End Sub
 
 Private Sub Stop_Click()
     ATLMsgTrafficCtl1.StopGraph
 End Sub