Click here to Skip to main content
15,886,035 members
Articles / Programming Languages / C++

Event Sinks

Rate me:
Please Sign up or sign in to vote.
4.11/5 (3 votes)
1 Mar 2007CPOL20 min read 54.4K   1K   32  
An introduction to event sinks in C++ in the context of ATL COM Add Ins.
// Connect.cpp : Implementation of CConnect
#include "stdafx.h"
#include "AddIn.h"
#include "Connect.h"
#include "DotOleErrors.h"
#include "CCommandBar0.h"
#include "CCommandBars.h"
#include "CCommandBarControl.h"
#include "CCommandBarControls.h"
#include "WordFind.h"
#include "CDocument0.h"

extern CAddInModule _AtlModule;

CConnect::CConnect()
{
	m_oWordFindButton = NULL;
}

// When run, the Add-in wizard prepared the registry for the Add-in.
// At a later time, if the Add-in becomes unavailable for reasons such as:
//   1) You moved this project to a computer other than which is was originally created on.
//   2) You chose 'Yes' when presented with a message asking if you wish to remove the Add-in.
//   3) Registry corruption.
// you will need to re-register the Add-in by building the WordFindFacilitySetup project, 
// right click the project in the Solution Explorer, then choose install.


// CConnect
STDMETHODIMP CConnect::OnConnection(IDispatch *pApplication, AddInDesignerObjects::ext_ConnectMode /*ConnectMode*/, IDispatch *pAddInInst, SAFEARRAY ** /*custom*/ )
{
	pApplication->QueryInterface(__uuidof(IDispatch), (LPVOID*)&m_pApplication);
	pAddInInst->QueryInterface(__uuidof(IDispatch), (LPVOID*)&m_pAddInInstance);

	try
	{
		m_oWordApp.AttachDispatch(pApplication);
	}

	catch( DotOleException* e )
	{
		DotOleErrors::OleErrorMessages(e);
	}

	catch( DotOleDispatchException* e )
	{
		DotOleErrors::DispatchErrorMessages(e);
	}

	return S_OK;
}

STDMETHODIMP CConnect::OnDisconnection(AddInDesignerObjects::ext_DisconnectMode /*RemoveMode*/, SAFEARRAY ** /*custom*/ )
{
	m_pApplication = NULL;
	m_pAddInInstance = NULL;
	return S_OK;
}

STDMETHODIMP CConnect::OnAddInsUpdate (SAFEARRAY ** /*custom*/ )
{
	return S_OK;
}

STDMETHODIMP CConnect::OnStartupComplete (SAFEARRAY ** /*custom*/ )
{
	RemoveMenuItems();
	AddMenuItems();
	return S_OK;
}

STDMETHODIMP CConnect::OnBeginShutdown (SAFEARRAY ** /*custom*/ )
{
	RemoveMenuItems();
	return S_OK;
}

void CConnect::AddMenuItems()
{
	try
	{
		CCommandBars oCommBars = m_oWordApp.get_CommandBars();
		CCommandBar0 oMenuBar = oCommBars.get_ActiveMenuBar();
		CCommandBarControls oMenuBarControls = oMenuBar.get_Controls();

		long count = oMenuBarControls.get_Count();

		for (long iii=1; iii<=count; iii++)
		{
			CComVariant vLong(iii);
			CCommandBarControl oControl = oMenuBarControls.get_Item(vLong);
			if ( oControl.get_Caption().Compare( "&Window" ) == 0 )
			{
				MsoControlType type = msoControlPopup;
				m_oWordFindPopup = oMenuBarControls.Add( 
					CComVariant(type), 
					vOpt, 
					vOpt, 
					CComVariant(iii), 
					vOpt);
				m_oWordFindPopup.put_Tag("WordFindFacility Popup");
				m_oWordFindPopup.put_Caption("&My Menu");
				m_oWordFindPopup.put_Visible(TRUE);
				m_oWordFindPopup.put_TooltipText("A Fairly Useless Word Find Facility");
				break;
			}
		}

		CCommandBarControls controls = m_oWordFindPopup.get_Controls();

		MsoControlType type = msoControlButton;
		m_oWordFindButton = controls.Add( 
			CComVariant(type), 
			vOpt, 
			vOpt, 
			CComVariant(1), 
			vOpt);
		m_oWordFindButton.put_Tag("WordFindFacility Popup");
		m_oWordFindButton.put_Caption("&Find...");
		m_oWordFindButton.put_Visible(TRUE);
		m_oWordFindButton.put_TooltipText("A Fairly Useless Word Find Facility");
		MsoButtonStyle style = msoButtonCaption;
		m_oWordFindButton.put_Style(style);
		m_oWordFindButton.put_OnAction( "!<WordFindFacility.Connect>" );
	}

	catch( DotOleException* e )
	{ 
		DotOleErrors::OleErrorMessages(e); 
	}
	catch( DotOleDispatchException* e )
	{ 
		DotOleErrors::DispatchErrorMessages(e); 
	} 

	HRESULT hr;

	hr = FindMenuItemEventImpl::DispEventAdvise( m_oWordFindButton );
	if (FAILED(hr))
	{
		DotOleErrors::HRErrorMessages(hr,"DispEventAdvise FAIL");
	}
}

void CConnect::RemoveMenuItems()
{
	HRESULT hr;

	if ( m_oWordFindButton != NULL )
	{
		hr = FindMenuItemEventImpl::DispEventUnadvise( m_oWordFindButton );
		if (FAILED(hr))
		{
			DotOleErrors::HRErrorMessages(hr,"DispEventUnAdvise FAIL");
		}

		m_oWordFindButton.ReleaseDispatch();
	}

	try
	{
		CCommandBars oCommBars = m_oWordApp.get_CommandBars();
		CCommandBar0 oMenuBar = oCommBars.get_ActiveMenuBar();
		CCommandBarControls oMenuBarControls = oMenuBar.get_Controls();

		long count = oMenuBarControls.get_Count();
		for (long iii=1; iii<=count; iii++)
		{
			CComVariant vLong(iii);
			CCommandBarPopup oPopup = oMenuBarControls.get_Item(vLong);
			if ( oPopup.get_Caption().Compare( "&My Menu" ) == 0 )
			{
				CCommandBarControls oPopupControls = oPopup.get_Controls();
				while ( oPopupControls.get_Count() > 0 )
				{
					CCommandBarButton button = oPopupControls.get_Item( CComVariant((long)1) );
					button.Delete(vOpt);
				}
			oPopup.Delete(vOpt);
			count--;
			}
		}
	}
	catch( DotOleException* e )
	{
		DotOleErrors::OleErrorMessages(e);
	}
	catch( DotOleDispatchException* e )
	{
		DotOleErrors::DispatchErrorMessages(e);
	}
}

void _stdcall CConnect::OnFindMenuItemClick(LPDISPATCH button, VARIANT_BOOL* cancelDefault)
{
	try
	{
		CDocument0 oActiveDocument = m_oWordApp.get_ActiveDocument();
		CWordFind dlg( &oActiveDocument );
		dlg.DoModal();
	}
	catch( DotOleException* e )
	{
	DotOleErrors::OleErrorMessages(e);
	}
	catch( DotOleDispatchException* e )
	{
		DotOleErrors::DispatchErrorMessages(e);
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Dotric Pty Ltd
Australia Australia
Doug graduated from Deakin University Geelong, Victoria, Australia with a Bachelor of Engineering.

Early in his career, Doug worked on an automated system for testing telephone lines. This system used a network of DEC PDP11s. The software was written in Oregon Pascal with an event driven structure. This early involvement in event driven structures proved to be an invaluable stepping stone into Windows programming some years latter.

Doug completed a Graduate Diploma in Education at La Trobe University to become a qualified secondary school Mathematics and Physics teacher. Subsequent IT contracts were with universities. One such contract was to add functionality to MSN Messenger.

In recent times Doug has been working on database and Android applications.

Comments and Discussions