Events |
They are used to send notifications between two objects in COM. In order to receive notifications, it is necessary to:
Estos son usados para enviar notificaciones entre dos objetos en COM. A fin de recibir notificaciones es necesario: |
Microsoft Word Events |
You can use the Object Browser to explore Microsoft Word events as shown below. If you are using #import, you can use Class View to explore Microsoft Word events (see figure below). Usted puede usar el Explorador de Objetos para explorar los eventos de Microsoft Word como se muestra debajo. Si usted está usando #import, usted puede usar la Vista de Clases para explorar los eventos de Microsoft Word (vea la figura below). |
Problem 1 |
Create a program so called MsWait to display in a MessageBox the name of the Microsoft Word Document using the DocumentBeforePrint event. Cree un programa llamado MsWait para mostrar en una Caja de Mensaje el nombre del documento de Microsoft Word usando el evento DocumentBeforePrint. |
Step A |
Create Wintempla dialog application called MsWait. Cree una aplicación de diálogo de Wintempla llamada MsWait. |
Step B |
Use the command #import to create the files: mso.tlh, mso.tli and msword.tlh. If you have created these files in another project, you may just copy these files from that project (after copying the files, do not forget to add these files to your project in Microsoft Visual Studio). Use el comando #import para crear los archivos: mso.tlh, mso.tli y msword.tlh. Si usted ya ha creado estos archivos en otro proyecto, usted puede solo copiar estos archivos desde este proyecto (después de copiar estos archivos, no se olvide de agregar estos archivos a su proyecto de Microsoft Visual Studio). |
Step C |
From the menu: Tools > Add Wintempla Item... add an IUnknown class called EventListener as shown. Then edit the files: EventListener.h and EventListener.cpp. Desde el menú: Tools > Add Wintempla Item... agregue una clase IUnknown llamada EventListener como se muestra. Entonces edite los archivos: EventListener.h y EventListener.cpp. |
EventListener.h |
#pragma once //_____________________________________________ EventListener.h #include "resource.h" #include "msword.tlh" #include "mso.tlh" // You can get the interface ID (IID) from the msword.tlh file const IID IID_IApplicationEvents2 ={0x000209fe,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; class EventListener : public IDispatch { public: EventListener(); ~EventListener(); HWND hWnd; //____________________________________________________ IUnknown IUNKNOWN_BEGIN (IDispatch) QUERY_INTERFACE(IID_IDispatch, IDispatch) QUERY_INTERFACE(IID_IApplicationEvents2, Word::IApplicationEvents2) IUNKNOWN_END //_______________________________________________________ IDispatch STDMETHOD (GetTypeInfoCount) (UINT *pctinfo); STDMETHOD (GetTypeInfo) (UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo); STDMETHOD (GetIDsOfNames) (REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); STDMETHOD (Invoke) (DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); //_______________________________________________________Word::ApplicationEvents2 STDMETHOD (Startup)(); STDMETHOD (Quit)(); STDMETHOD (DocumentChange)(); STDMETHOD (DocumentOpen)(/*[in]*/ IDispatch* document); STDMETHOD (DocumentBeforeClose)(/*[in]*/ IDispatch* document, /*[in]*/ VARIANT_BOOL* Cancel); STDMETHOD (DocumentBeforePrint)(/*[in]*/ IDispatch* document, /*[in]*/ VARIANT_BOOL* Cancel); STDMETHOD (DocumentBeforeSave)(/*[in]*/ IDispatch* document, /*[in]*/ VARIANT_BOOL* SaveAsUI, /*[in]*/ VARIANT_BOOL * Cancel); STDMETHOD (NewDocument)(/*[in]*/ IDispatch* document); STDMETHOD (WindowActivate)(/*[in]*/ IDispatch* document, /*[in]*/ IDispatch* window); STDMETHOD (WindowDeactivate)(/*[in]*/ IDispatch* document, /*[in]*/ IDispatch* window); STDMETHOD (WindowSelectionChange)(/*[in]*/ IDispatch* selection); STDMETHOD (WindowBeforeRightClick)(/*[in]*/ IDispatch* selection, /*[in]*/ VARIANT_BOOL* Cancel); STDMETHOD (WindowBeforeDoubleClick)(/*[in]*/ IDispatch* selection, /*[in]*/ VARIANT_BOOL* Cancel); }; |
EventListener.cpp |
#include "stdafx.h" //_____________________________________________ EventListener.cpp #include "EventListener.h" EventListener::EventListener() { hWnd = NULL; } EventListener::~EventListener() { } //_______________________________________________________ IDispatch STDMETHODIMP EventListener::GetTypeInfoCount(UINT *pctinfo) { *pctinfo = 0; return S_OK; } STDMETHODIMP EventListener::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { return E_NOTIMPL; } STDMETHODIMP EventListener::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { return E_NOTIMPL; } STDMETHODIMP EventListener::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { if (riid != IID_NULL) return E_INVALIDARG; switch (dispIdMember) { case 0x00000001: // Startup() return Startup(); case 0x00000002: // Quit() return Quit(); case 0x00000003: // DocumentChange() return DocumentChange(); case 0x00000004: //DocumentOpen(/*[in]*/ struct Word::_Document * Doc) if (pDispParams->cArgs != 1) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; return DocumentOpen(pDispParams->rgvarg[0].pdispVal); case 0x00000006: // DocumentBeforeClose(/*[in]*/ struct Word::_Document * Doc, /*[in]*/ VARIANT_BOOL * Cancel) if (pDispParams->cArgs != 2) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != (VT_BOOL | VT_BYREF)) return E_INVALIDARG; return DocumentBeforeClose(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].pboolVal); case 0x00000007: // DocumentBeforePrint(); if (pDispParams->cArgs != 2) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != (VT_BOOL | VT_BYREF)) return E_INVALIDARG; return DocumentBeforePrint(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].pboolVal); case 0x00000008: // DocumentBeforeSave if (pDispParams->cArgs != 3) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != (VT_BOOL | VT_BYREF)) return E_INVALIDARG; if (pDispParams->rgvarg[2].vt != (VT_BOOL | VT_BYREF)) return E_INVALIDARG; return DocumentBeforeSave(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].pboolVal, pDispParams->rgvarg[2].pboolVal); case 0x00000009: // NewDocument if (pDispParams->cArgs != 1) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; return NewDocument(pDispParams->rgvarg[0].pdispVal); case 0x0000000a: // WindowActivate if (pDispParams->cArgs != 2) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != VT_DISPATCH) return E_INVALIDARG; return WindowActivate(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].pdispVal); case 0x0000000b: // WindowDeactivate if (pDispParams->cArgs != 2) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != VT_DISPATCH) return E_INVALIDARG; return WindowDeactivate(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].pdispVal); case 0x0000000c: // WindowSelectionChange if (pDispParams->cArgs != 1) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; return WindowSelectionChange(pDispParams->rgvarg[0].pdispVal); case 0x0000000d: // WindowBeforeRightClick if (pDispParams->cArgs != 2) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != (VT_BOOL | VT_BYREF)) return E_INVALIDARG; return WindowBeforeRightClick(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].pboolVal); case 0x0000000e: // WindowBeforeDoubleClick if (pDispParams->cArgs != 2) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != (VT_BOOL | VT_BYREF)) return E_INVALIDARG; return WindowBeforeDoubleClick(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].pboolVal); } return S_OK; } //_______________________________________________________Word::ApplicationEvents2 STDMETHODIMP EventListener::Startup() { return S_OK; } STDMETHODIMP EventListener::Quit() { return S_OK; } STDMETHODIMP EventListener::DocumentChange() { return S_OK; } STDMETHODIMP EventListener::DocumentOpen(IDispatch* document) { return S_OK; } STDMETHODIMP EventListener::DocumentBeforeClose(IDispatch* document, VARIANT_BOOL * Cancel) { //Com::Object Document(document); //*Cancel = -1; // To prevent closing the document return S_OK; } STDMETHODIMP EventListener::DocumentBeforePrint(IDispatch* document, VARIANT_BOOL * Cancel) { Com::Object Document(document); _variant_t fullname; Document.Get(L"Fullname", fullname); ::MessageBox(hWnd, fullname.bstrVal, L"Microsoft Word is Printing", MB_OK | MB_ICONINFORMATION); return S_OK; } STDMETHODIMP EventListener::DocumentBeforeSave(IDispatch* document, VARIANT_BOOL * SaveAsUI, VARIANT_BOOL * Cancel) { //Com::Object Document(document); return S_OK; } STDMETHODIMP EventListener::NewDocument(IDispatch* document) { //Com::Object Document(document); return S_OK; } STDMETHODIMP EventListener::WindowActivate(IDispatch* document, IDispatch* dindow) { //Com::Object Document(document); //Com::Object Window(window); return S_OK; } STDMETHODIMP EventListener::WindowDeactivate(IDispatch* Document, IDispatch* Window) { //Com::Object Document(document); //Com::Object Window(window); return S_OK; } STDMETHODIMP EventListener::WindowSelectionChange(IDispatch* selection) { //Com::Object Selection(selection); return S_OK; } STDMETHODIMP EventListener::WindowBeforeRightClick(IDispatch* Selection, VARIANT_BOOL * Cancel) { //Com::Object Selection(selection); return S_OK; } STDMETHODIMP EventListener::WindowBeforeDoubleClick(IDispatch* Selection, VARIANT_BOOL * Cancel) { //Com::Object Selection(selection); return S_OK; } |
Step D |
Edit the files: MsWait.h and MsWait.cpp. Edit the files: MsWait.h y MsWait.cpp. |
MsWait.h |
#pragma once //______________________________________ MsWait.h #include "Resource.h" #include "msword.tlh" #include "mso.tlh" #include "EventListener.h" class MsWait: public Win::Dialog { public: MsWait() { ::CoInitialize(NULL); listenerCookie = 0; connectionPoint = NULL; } ~MsWait() { if (connectionPoint != NULL) connectionPoint = NULL; ::CoUninitialize(); } DWORD listenerCookie; EventListener eventListener; IConnectionPointPtr connectionPoint; protected: ... }; |
MsWait.cpp |
... void MsWait::Window_Open(Win::Event& e) { eventListener.hWnd = hWnd; Word::_ApplicationPtr Application = NULL; Word::DocumentsPtr Documents = NULL; Word::_DocumentPtr Document = NULL; _variant_t vtTemplate(L"Normal"); _variant_t vtTrue(true); _variant_t vtVisible(true); _variant_t vtFalse(false); _variant_t newBlankDocument((short)Word::WdNewDocumentType::wdNewBlankDocument); HRESULT hr; Com::Exception ex; IConnectionPointContainerPtr connectionPointContainer = NULL; try { //_____________________________________________Open MS Word hr = Application.CreateInstance(L"Word.Application"); ex.ok(L"Application.CreateInstance", hr); //_____________________________________________ Application->put_Visible hr = Application->put_Visible(vtTrue); ex.ok(L"Application->put_Visible", hr); //_____________________________________________ Application->get_Documents hr = Application->get_Documents(&Documents); ex.ok(L"Application->get_Documents", hr); //_____________________________________________ Documents->Add hr = Documents->Add(&vtTemplate, &vtFalse, &newBlankDocument, &vtVisible, &Document); ex.ok(L"Documents->Add", hr); // //_bstr_t fullname; //hr = Document->get_FullName(&fullname.GetBSTR()); //ex.ok(L"Documents->Add", hr); //_____________________________________________ IConnectionPointContainer provides access to one or more IConnectionPoint connectionPointContainer = Application; if (connectionPointContainer == NULL) ex.ThrowNullPointer(L"connectionPointContainer"); //_____________________________________________ Find the IConnectionPoint for Microsoft events connectionPointContainer->FindConnectionPoint(IID_IApplicationEvents2, &connectionPoint); if (connectionPoint == NULL) ex.ThrowNullPointer(L"connectionPoint"); //______________________________________________ We would like to receive Microsoft Word events! hr = connectionPoint->Advise(&eventListener, &listenerCookie); ex.ok(L"connectionPoint->Advise", hr); eventListener.AddRef(); } catch (Com::Exception& excep) { excep.Display(hWnd, L"MsWait"); } catch (_com_error excep) { Com::Exception::Display(hWnd, excep, L"MsWait"); } } void MsWait::btShutdowListener_Click(Win::Event& e) { if (connectionPoint == NULL) return; HRESULT hr; Com::Exception ex; try { // We do not want to receive Microsoft Word events any longer! // If Microsoft Word is closed, you cannot longer call Unadvise, thus // you must call Unadvise while Microsoft Word is open. // Note that closing the last document, will close Microsoft Word hr = connectionPoint->Unadvise(listenerCookie); ex.ok(L"connectionPoint->UnAdvise", hr); listenerCookie = 0; } catch (Com::Exception& excep) { excep.Display(hWnd, L"MsWait"); } catch (_com_error excep) { Com::Exception::Display(hWnd, excep, L"MsWait"); } connectionPoint = NULL; } |
Step E |
To test the program:
Para probar el programa:
|
Word::DocumentEvents |
Methods of Word::DocumentEvents2 (you may use the Object Browser to know more about the events of the Word::Document):
Métodos de Word::DocumentEvents2 (usted puede usar el Explorador de Objetos para conocer más sobre los eventos del Word::Document):
|
Content Controls |
They allow designing Microsoft Word documents than can have a user interface (GUI: check box, radio button, drop-down list, etc.). Content Controls can be also used to prevent users from editing part of a document. Content Controls can be used to connect Microsoft Word to a database. By default the Developer Tab is hidden in Microsoft Word; you can customize Microsoft Word to make the Developer Tab visible as shown below. Estos permiten diseñar documentos de Microsoft Word que pueden tener una interface para el usuario (GUI: check box, radio button, drop-down list, etc.). Los Controles de Contenido también pueden ser usados para evitar que los usuarios editen parte del documento. Los Controles de Contenido pueden ser usados para conectar Microsoft Word a una base de datos. Por defecto la Pestaña del Programador (Ficha del Programador) está escondida en Microsoft Word; usted puede personalizar Microsoft Word para hacer visible la Pestaña del Programador como se muestra debajo. |
Word 2016 |
Use File > Options > Customize Ribbon and on the second column, check Developer. Use Archivo > Opciones > Personalizar Cinta de Opciones y en la segunda columna, marque Desarrollador. |
Building Blocks |
They are predefined pieces of document content that can be saved for future use. They can contain: text, tables, paragraphs, etc. They can be used for headers, or parts of a document that are frequently required. Estas son piezas predefinidas con el contenido de un documento que pueden ser almacenadas para usarlas más tarde. Estas puede contener: texto, tablas, párrafos, etc. Estos pueden ser usados para encabezados, o partes de un documento que son requeridas con frecuencia. |
Problem 2 |
Create a program so called MsAlert to test Word.Document.DocumentEvents. Please review the steps of the previous problem before working on this problem. You will need the files: mso.tlh, mso.tli and msword.tlh. Cree un programa llamado MsAlert para probar Word.Document.DocumentEvents. Por favor, repase los pasos del problema previo antes de trabajar en este problema. Usted necesitará los archivos: mso.tlh, mso.tli y msword.tlh. |
DocEventListener.h |
#pragma once //_____________________________________________ DocEventListener.h #include "resource.h" #include "msword.tlh" #include "mso.tlh" // You can get the interface ID (IID) from the msword.tlh file const IID IID_DocumentEvents2 ={0x00020a02,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; class DocEventListener : public IDispatch { public: DocEventListener(); ~DocEventListener(); Win::Textbox* textbox; //____________________________________________________ IUnknown IUNKNOWN_BEGIN (IDispatch) QUERY_INTERFACE(IID_IDispatch, IDispatch) QUERY_INTERFACE(IID_DocumentEvents2, Word::DocumentEvents2) IUNKNOWN_END //_______________________________________________________ IDispatch STDMETHOD (GetTypeInfoCount) (UINT *pctinfo); STDMETHOD (GetTypeInfo) (UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo); STDMETHOD (GetIDsOfNames) (REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); STDMETHOD (Invoke) (DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); //_______________________________________________________Word::DocumentEvents2 STDMETHOD (Close)(); STDMETHOD (ContentControlAfterAdd)(/*[in]*/ IDispatch* newContentControl, /*[in]*/ VARIANT_BOOL* UndoRedo); STDMETHOD (ContentControlBeforeDelete)(/*[in]*/ IDispatch* newContentControl, /*[in]*/ VARIANT_BOOL UndoRedo); STDMETHOD (ContentControlOnExit)(/*[in]*/ IDispatch* contentControl, /*[in]*/ VARIANT_BOOL* Cancel); STDMETHOD (ContentControlOnEnter)(/*[in]*/ IDispatch* contentControl); STDMETHOD (BuildingBlockInsert)(IDispatch* range, BSTR name, BSTR category, BSTR blockType, BSTR templatex); // ... }; |
DocEventListener.cpp |
#include "stdafx.h" //_____________________________________________ DocEventListener.cpp #include "DocEventListener.h" DocEventListener::DocEventListener() { textbox = NULL; } DocEventListener::~DocEventListener() { } //_______________________________________________________ IDispatch STDMETHODIMP DocEventListener::GetTypeInfoCount(UINT *pctinfo) { *pctinfo = 0; return S_OK; } STDMETHODIMP DocEventListener::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { return E_NOTIMPL; } STDMETHODIMP DocEventListener::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { return E_NOTIMPL; } STDMETHODIMP DocEventListener::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { if (riid != IID_NULL) return E_INVALIDARG; switch (dispIdMember) { case 0x00000006: // Close() return Close(); case 0x0000000C: // ContentControlAfterAdd if (pDispParams->cArgs != 2) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != (VT_BOOL | VT_BYREF)) return E_INVALIDARG; return ContentControlAfterAdd(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].pboolVal); case 0x0000000D: // ContentControlBeforeDelete if (pDispParams->cArgs != 2) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != (VT_BOOL)) return E_INVALIDARG; return ContentControlBeforeDelete(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].boolVal); case 0x0000000E: //ContentControlOnExit if (pDispParams->cArgs != 2) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != (VT_BOOL | VT_BYREF)) return E_INVALIDARG; return ContentControlOnExit(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].pboolVal); case 0x0000000F: // ContentControlOnEnter if (pDispParams->cArgs != 1) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; return ContentControlOnEnter(pDispParams->rgvarg[0].pdispVal); case 0x00000012: // BuildingBlockInsert if (pDispParams->cArgs != 5) return E_INVALIDARG; if (pDispParams->rgvarg[0].vt != VT_DISPATCH) return E_INVALIDARG; if (pDispParams->rgvarg[1].vt != VT_BSTR) return E_INVALIDARG; if (pDispParams->rgvarg[2].vt != VT_BSTR) return E_INVALIDARG; if (pDispParams->rgvarg[3].vt != VT_BSTR) return E_INVALIDARG; if (pDispParams->rgvarg[4].vt != VT_BSTR) return E_INVALIDARG; return BuildingBlockInsert(pDispParams->rgvarg[0].pdispVal, pDispParams->rgvarg[1].bstrVal, pDispParams->rgvarg[2].bstrVal, pDispParams->rgvarg[3].bstrVal, pDispParams->rgvarg[4].bstrVal); // ... } return S_OK; } //_______________________________________________________Word::DocumentEvents2 STDMETHODIMP DocEventListener::Close() { textbox->AppendText(L"Close\r\n"); return S_OK; } STDMETHODIMP DocEventListener::ContentControlAfterAdd(IDispatch* newContentControl, VARIANT_BOOL* UndoRedo) { //Com::Object NewContentControl(newContentControl); textbox->AppendText(L"ContentControlAfterAdd\r\n"); return S_OK; } STDMETHODIMP DocEventListener::ContentControlBeforeDelete(IDispatch* newContentControl, VARIANT_BOOL UndoRedo) { //Com::Object NewContentControl(newContentControl); textbox->AppendText(L"ContentControlBeforeDelete\r\n"); return S_OK; } STDMETHODIMP DocEventListener::ContentControlOnExit(IDispatch* contentControl, VARIANT_BOOL* Cancel) { //Com::Object ContentControl(contentControl); textbox->AppendText(L"ContentControlOnExit\r\n"); return S_OK; } STDMETHODIMP DocEventListener::ContentControlOnEnter(IDispatch* contentControl) { //Com::Object ContentControl(contentControl); textbox->AppendText(L"ContentControlOnEnter\r\n"); return S_OK; } STDMETHODIMP DocEventListener::BuildingBlockInsert(IDispatch* range, BSTR name, BSTR category, BSTR blockType, BSTR templatex) { //Com::Object Range(range); textbox->AppendText(L"BuildingBlockInsert\r\n"); return S_OK; } |
MsAlert.h |
#pragma once //______________________________________ MsAlert.h #include "Resource.h" #include "msword.tlh" #include "mso.tlh" #include "DocEventListener.h" class MsAlert: public Win::Dialog { public: MsAlert() { ::CoInitialize(NULL); listenerCookie = 0; connectionPoint = NULL; } ~MsAlert() { if (connectionPoint != NULL) connectionPoint = NULL; ::CoUninitialize(); } DWORD listenerCookie; DocEventListener docEventListener; IConnectionPointPtr connectionPoint; protected: //______ Wintempla GUI manager section begin: DO NOT EDIT AFTER THIS LINE Win::Button btShutdownListener; Win::Textbox tbxOutput; protected: ... }; |
MsAlert.cpp |
... void MsAlert::Window_Open(Win::Event& e) { docEventListener.textbox = &tbxOutput; Word::_ApplicationPtr Application = NULL; Word::DocumentsPtr Documents = NULL; Word::_DocumentPtr Document = NULL; _variant_t vtTemplate(L"Normal"); _variant_t vtTrue(true); _variant_t vtVisible(true); _variant_t vtFalse(false); _variant_t newBlankDocument((short)Word::WdNewDocumentType::wdNewBlankDocument); HRESULT hr; Com::Exception ex; IConnectionPointContainerPtr connectionPointContainer = NULL; try { //_____________________________________________Open MS Word hr = Application.CreateInstance(L"Word.Application"); ex.ok(L"Application.CreateInstance", hr); //_____________________________________________ Application->put_Visible hr = Application->put_Visible(vtTrue); ex.ok(L"Application->put_Visible", hr); //_____________________________________________ Application->get_Documents hr = Application->get_Documents(&Documents); ex.ok(L"Application->get_Documents", hr); //_____________________________________________ Documents->Add hr = Documents->Add(&vtTemplate, &vtFalse, &newBlankDocument, &vtVisible, &Document); ex.ok(L"Documents->Add", hr); //_____________________________________________ IConnectionPointContainer provides access to one or more IConnectionPoint connectionPointContainer = Document; if (connectionPointContainer == NULL) ex.ThrowNullPointer(L"connectionPointContainer"); //_____________________________________________ Find the IConnectionPoint for Document events connectionPointContainer->FindConnectionPoint(IID_DocumentEvents2, &connectionPoint); if (connectionPoint == NULL) ex.ThrowNullPointer(L"connectionPoint"); //______________________________________________ We would like to receive Document events! hr = connectionPoint->Advise(&docEventListener, &listenerCookie); ex.ok(L"connectionPoint->Advise", hr); docEventListener.AddRef(); } catch (Com::Exception& excep) { excep.Display(hWnd, L"MsAlert"); } catch (_com_error excep) { Com::Exception::Display(hWnd, excep, L"MsAlert"); } } void MsAlert::btShutdownListener_Click(Win::Event& e) { if (connectionPoint == NULL) return; HRESULT hr; Com::Exception ex; try { // We do not want to receive Document events any more hr = connectionPoint->Unadvise(listenerCookie); ex.ok(L"connectionPoint->UnAdvise", hr); listenerCookie = 0; } catch (Com::Exception& excep) { excep.Display(hWnd, L"MsAlert"); } catch (_com_error excep) { Com::Exception::Display(hWnd, excep, L"MsAlert"); } connectionPoint = NULL; } |