The Add-In sample application implements the ExpressAddin as follows:
...
BOOL AddinSampleDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetupDialog();
try
{
// Initialize a smart pointer to the IExpressAddin interface.
HRESULT hResult = m_spIAddin.CreateInstance( CLSID_ExpressAddin );
if (FAILED(hResult))
{
return FALSE;
}
// Run the Startup() interface method.
m_spIAddin->Startup(ComposeStartupXml());
...
return TRUE;
}
...
...
_bstr_t AddinSampleDlg::ComposeStartupXml()
{
// Specify the startup XML for the ApplicationName,
// the ApplicationID, and the array of Application Mimetypes.
_bstr_t startupXml = _T( "" );
startupXml += _T("<?xml version=\"1.0\" ?>");
startupXml += _T("<object key=\"addInConfiguration\" version=\"1.0\">");
startupXml += _T("<setting key=\"applicationName\">AddinSampleApp</setting>");
startupXml += _T("<setting key=\"useUnifiedLogin\">true</setting>");
startupXml += _T("<array key=\"applicationMimeTypes\">");
startupXml += _T("<value>text/xml</value>");
startupXml += _T("<value>text/html</value>");
startupXml += _T("<value>text/txt</value>");
startupXml += _T("<value>text/plain</value>");
startupXml += _T("<value>application/msword</value>");
startupXml += _T("</array>");
startupXml += _T("</object>");
return startupXml;
}
...
...
void AddinSampleDlg::OnFileNetOpenViaSelectItem()
{
HRESULT hResult = S_OK;
try
{
// Run the "Open using Select Item" process.
hResult = m_spIAddin->RunCommand( _bstr_t( _T( "ExpressAddin.OpenSelectItem" ) ) );
}
catch ( _com_error &err )
{
AfxMessageBox( err.ErrorMessage() );
}
catch( ... )
...
}
void AddinSampleDlg::OnFileNetOpenViaMyCheckouts()
{
HRESULT hResult = S_OK;
try
{
// Display checked out list and open from the list.
hResult = m_spIAddin->RunCommand( _bstr_t( _T( "ExpressAddin.OpenMyCheckouts" ) ) );
}
catch ( _com_error &err )
{
...
}
void AddinSampleDlg::OnFileNetAddViaWizard()
{
HRESULT hResult = S_OK;
try
{
// Run the "Add using Wizard" process.
hResult = m_spIAddin->RunCommand( _bstr_t( _T( "ExpressAddin.AddDocumentUseAddWizard" ) ) );
}
catch ( _com_error &err )
{
...
}
...
After the request has been made to execute a particular command, the ExpressAddin component and FileNet Application Integration Add-In infrastructure continue to perform operations until information or behavior is required from the Add-In sample application. Events are then fired to request the information or behavior from the Add-In.
...
// Event sink map.
BEGIN_SINK_MAP(CEventHandler)
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 1, OnAppBeginWaitCursor, &gNoArgsHResult() )
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 2, OnAppCloseActiveDocument, &gNoArgsHResult() )
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 3, OnAppEndWaitCursor, &gNoArgsHResult() )
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 4, OnAppGetActiveDocumentPath, &gPtrBStrArg() )
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 5, OnAppExistsActiveDocument, &gPtrBoolArg() )
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 6, OnAppInsertHyperlink, &gBStrArg() )
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 7, OnAppIsActiveDocumentModified, &gPtrBoolArg() )
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 8, OnAppIsActiveDocumentNew, &gPtrBoolArg() )
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 9, OnAppSaveModifiedActiveDocument, &gNoArgsHResult() )
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 10, OnAppSaveNewActiveDocument, &gNoArgsHResult() )
SINK_ENTRY_INFO( 0, __uuidof(_IExpressAddinEvents), 11, OnAppOpenDocument, &gBStrArg() )
END_SINK_MAP()
...
In the file Eventhandler.cpp, each event handler performs the required action
and transfers any requested information back to the calling process:...
// --- Event handler implementations ---
HRESULT __stdcall CEventHandler::OnAppBeginWaitCursor()
{
// Display the application's wait cursor.
AfxGetMainWnd()->BeginWaitCursor();
return S_OK;
}
HRESULT __stdcall CEventHandler::OnAppEndWaitCursor()
{
// End the application's wait cursor.
AfxGetMainWnd()->EndWaitCursor();
return S_OK;
}
HRESULT __stdcall CEventHandler::OnAppExistsActiveDocument( VARIANT_BOOL *pExistsActiveDocument )
{
// Query the document object to determine if there is an active document.
if( m_pDocument->ExistsActiveDocument() )
{
*pExistsActiveDocument = VARIANT_TRUE;
}
else
{
*pExistsActiveDocument = VARIANT_FALSE;
}
return S_OK;
}
...
This process continues until the command has completed execution. The execution of commands (Step 3) and the handling of events (Step 4) continue until the user chooses to terminate the application.
...
void AddinSampleDlg::OnOK()
{
// Disconnect the event handling.
Disconnect();
// Call shutdown on the COM Server.
HRESULT hResult = m_spIAddin->Shutdown();
// Base class call.
CDialog::OnOK();
}
void AddinSampleDlg::OnCancel()
{
// Disconnect the event handling.
Disconnect();
// Call shutdown on the COM Server.
HRESULT hResult = m_spIAddin->Shutdown();
// Base class call.
CDialog::OnCancel();
}
...