Run the Add –> Class command from the right-click menu in Visual Studio. This will display the dialog shown below. From the category list select Inventor and then click the Add button.
In the Short Name field, enter the name for the class you want to create that will handle the events. This name should not be the same as the Inventor object that supports the event or a name clash will occur. For example, in this case I want to connect to the ApplicationEvents. I cannot use this name and have instead chosen “AppEvents” for the name of the class for this example.
On the Inventor Events tab you select which event sink you want to implement. The wizard provides a list of the possible event sinks. In this case the ApplicationEventsSink has been chosen.
Once you’ve specified the name and selected the event sink to implement you can click the OK button. This will add two additional files to your project and insert some additional code. There are also some additional manual steps that you’ll need to perform to complete the implementation.
The first step is to declare an instance of the class that was created by the ATL Wizard to handle these events. In this example the name specified when using the Inventor Add-In Wizard to create the project was “test”. The declaration of the event sink object is done in the .h file of the add-in class definition. The shaded line below illustrates the additional code that was added to testAddInServer.h.
//----------------------------------------------------------------
//----- testAddInServer.h: Declaration of the CtestAddInServer
//----------------------------------------------------------------
#include "resource.h"
#include "AppEvents.h"
public:
CComPtr<Application> m_pApplication ;
CComPtr<ApplicationAddInSite> m_pAddInSite ;
CComPtr<ApplicationEventsObject> mpAppEvents ;
CComObject<CAppEvents> *mpAppSinkObject ;
//{{AFX_INV_VARS_DECL(CtestAddInServer)
//}}AFX_INV_VARS_DECL
The second step is to connect to the event source. The shaded code below was added to testAddInServer.cpp. The code in the Activate method connects to the event source while the code in the Deactivate method disconnects from the event source and cleans up.
//----------------------------------------------------------------
//----- testAddInServer.cpp : Implementation of CtestAddInServer
//----------------------------------------------------------------#include "StdAfx.h"
#include "test.h"
#include "testAddInServer.h"
#include "AppEvents.h"
//----------------------------------------------------------------
STDMETHODIMP CtestAddInServer::Activate (IDispatch *pDisp, VARIANT_BOOL FirstTime)
{
AFX_MANAGE_STATE (AfxGetStaticModuleState ()) ;
if ( pDisp == NULL )
return E_INVALIDARG ;
HRESULT hr =pDisp->QueryInterface (__uuidof (m_pAddInSite),
reinterpret_cast<void**>(&m_pAddInSite)) ;
ATLASSERT( SUCCEEDED( hr ) ) ;
if ( FAILED( hr ) )
return hr ;
//----- Get the application object.
hr =m_pAddInSite->get_Application (&m_pApplication) ;
ATLASSERT( SUCCEEDED( hr ) ) ;
if ( FAILED( hr ) )
return hr ;
//{{AFX_INV_INIT_EVENTS(CtestAddInServer)
hr = m_pApplication->get_ApplicationEvents(&mpAppEvents) ;
CComObject<CAppEvents>::CreateInstance(&mpAppSinkObject) ;
mpAppSinkObject->AddRef() ;
mpAppSinkObject->DispEventAdvise(mpAppEvents) ;
//}}AFX_INV_INIT_EVENTS
//{{AFX_INV_INIT_CMDS(CtestAddInServer)
//}}AFX_INV_INIT_CMDS
return S_OK ;
}
//----------------------------------------------------------------
STDMETHODIMP CtestAddInServer::Deactivate ()
{
AFX_MANAGE_STATE (AfxGetStaticModuleState ()) ;
//{{AFX_INV_DEACT_EVENTS(CtestAddInServer)
if ( mpAppSinkObject != NULL )
{
mpAppSinkObject->DispEventUnadvise (
mpAppEvents) ;
mpAppSinkObject->Release () ;
mpAppSinkObject =NULL ;
mpAppEvents.Release () ;
mpAppEvents =NULL ;
}
//}}AFX_INV_DEACT_EVENTS
//{{AFX_INV_DEL_CMDS(CtestAddInServer)
//}}AFX_INV_DEL_CMDS
m_pAddInSite.Release () ;
m_pApplication.Release () ;
return S_OK ;
}
The final step is to add the implementation for the event. The code below is a section from the AppEvents.cpp file that was created by the ATL Object Wizard. This file contains the sink methods for all of the events supported the event set chosen in the ATL Object Wizard. By default, none of them are implemented. To implement any of the events you just add your code and change the return code from E_NOTIMPL to S_OK. The shaded section of code is the code that was modified in the OnNewDocument method.
//----------------------------------------------------------------
//----- AppEvents.cpp : Implementation of CAppEvents
//----------------------------------------------------------------
STDMETHODIMP CAppEvents::OnNewDocument (
struct Document *pDocumentObject,
enum EventTimingEnum BeforeOrAfter,
struct NameValueMap *pContext,
enum HandlingCodeEnum *pHandlingCode)
{
if ( pHandlingCode == NULL )
return (E_POINTER) ;
if ( BeforeOrAfter == kAfter ){
AFX_MANAGE_STATE (AfxGetStaticModuleState ()) ;
AfxMessageBox (_T("New Document Created."), MB_OK) ;
}
return (S_OK) ;
}