Hopefully, sometime soon I will have an article on the topic, but building Word addins are different from Outlook addins, as in the article, in the following ways:
first importing the Office 2000 typelibs as well as VBE typelibs:
in your projects stdafx.h add:
#import "C:\\Program Files\\Microsoft Office\\Office\\mso9.dll" rename_namespace("Office2000")
using namespace Office2000;
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.olb" rename_namespace("VBE6")
using namespace VBE6;
Next, import Word2000 and MS Addin typelibs.
at the top of addin.h file add
#import "C:\\Program Files\\Common Files\\designer\\MSADDNDR.DLL" raw_interfaces_only, raw_native_types, no_namespace, named_guids
#import "C:\\Program Files\\Microsoft Office\\Office\\MSWORD9.olb" rename("ExitWindows","MyExitWindows"),named_guids,rename_namespace("MSWord")
using namespace MSWord;
Moving on to implementation:
code for adding commandbars i.e. buttons,bands and menuitems are as in article.
To sink in Word events, for example for Application::DocumentOpen() and Application::DocumentClose() events, I use the ATL IDispEventSimpleImpl<> template. For more details, look at my article here, but briefly:
class ATL_NO_VTABLE CAddin :
public CComObjectRootEx,
public CComCoClass,
public ISupportErrorInfo,
public IDispatchImpl,
public IDispatchImpl<_IDTExtensibility2, &IID__IDTExtensibility2, &LIBID_AddInDesignerObjects>,
public IDispEventSimpleImpl<1,CAddin,&__uuidof(MSWord::ApplicationEvents2)>
{
private:
CComPtr m_spApp;
.....
.....
....
};
BEGIN_SINK_MAP(CAddin)
SINK_ENTRY_INFO(1,__uuidof(MSWord::ApplicationEvents2),3,DocClose,&DocCloseInfo)
SINK_ENTRY_INFO(1,__uuidof(MSWord::ApplicationEvents2),4,DocumentOpen,&DocumentOpenInfo)
END_SINK_MAP()
the event handler declarations:
void __stdcall DocumentOpen(IDispatchPtr ptr);
void __stdcall DocClose(void);
in .cpp file definition:
void __stdcall CAddin::DocumentOpen(IDispatchPtr ptr)
{
CComQIPtr<_Document> spDoc(ptr);
ATLASSERT(spDoc);
//do something with spDoc
}
void __stdcall CAddin::DocClose()
{
ATLTRACE("\nDocClose");
//add code to handle document close
}
finally call DispEventAdvise() and DispEventUnadvise() like:
....
STDMETHOD(OnConnection)(IDispatch * Application, ext_ConnectMode ConnectMode, IDispatch * AddInInst, SAFEARRAY * * custom)
{
CComQIPtr<_Application> spApp(Application);
ATLASSERT(spApp);
m_spApp = spApp;
HRESULT hr = DispEventAdvise(m_spApp);
if(FAILED(hr))
return hr;
return S_OK;
}
STDMETHOD(OnDisconnection)(ext_DisconnectMode RemoveMode, SAFEARRAY * * custom)
{
DispEventUnadvise(m_spApp);
return S_OK;
}
To register Word addins with the app, the relevant registry script looks like:
HKCU
{
Software
{
Microsoft
{
Office
{
Word
{
Addins
{
'WordAddin.Addin'
{
val FriendlyName = s 'WORD Custom Addin'
val Description = s 'Word Custom Addin'
val LoadBehavior = d '00000003'
val CommandLineSafe = d '00000001'
}
}
}
}
}
}
}
i.e. HKCU/Software/Microsoft/Office/Word/Addins/<your addin reg entries>
now you have a template Word addin that handles events. If everything has gone ok, now you should add your own implementation code!