This section describes how to instantiate the ADO event model. Below is
# ImportA specific example of instantiating the event model in an environment created by a pseudo-command.
Used in general instructionsAdoint. hAs a reference to the method declaration. However# ImportTherefore, some details in the General Instructions need to be slightly changed.
- # ImportPseudoinstructionsTypedef, Method declaration data type and key combination into its basic format.
- All virtual methods that must be overwritten are prefixed with"Raw _".
Some codes only reflect the encoding style.
- AdviseMethod usageIunknownThe pointer is throughQueryInterfaceExplicitly obtained by calling.
- You do not need to explicitly encode the destructor in the class definition.
- Users may need to make the encoding of QueryInterface, addref, and release more reliable.
- _ Uuidof ()The usage of pseudocommands can be extended to get the interface ID.
Finally, this example also contains some practical code.
- This example is written as a console application.
- The comment"
// Do some work
Insert your own code.
- By default, all event handlers do not perform any operations and cancel further notifications. The user shall insert the appropriate code of the application, and notification should be allowed if necessary.
// eventmodel.cpp : Defines the entry point for the console application.//#import "c:/Program Files/Common Files/System/ADO/msado15.dll" / no_namespace rename("EOF", "EndOfFile")#include <comdef.h>#include <stdio.h>//----The Connection events----------------------------------------------class CConnEvent : public ConnectionEventsVt{private: ULONG m_cRef; public: CConnEvent() { m_cRef = 0; }; ~CConnEvent() {}; STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); STDMETHODIMP raw_InfoMessage( struct Error *pError, EventStatusEnum *adStatus, struct _Connection *pConnection); STDMETHODIMP raw_BeginTransComplete( LONG TransactionLevel, struct Error *pError, EventStatusEnum *adStatus, struct _Connection *pConnection);
STDMETHODIMP raw_CommitTransComplete(
struct Error *pError, EventStatusEnum *adStatus, struct _Connection *pConnection); STDMETHODIMP raw_RollbackTransComplete( struct Error *pError, EventStatusEnum *adStatus, struct _Connection *pConnection); STDMETHODIMP raw_WillExecute( BSTR *Source, CursorTypeEnum *CursorType, LockTypeEnum *LockType, long *Options, EventStatusEnum *adStatus, struct _Command *pCommand, struct _Recordset *pRecordset, struct _Connection *pConnection); STDMETHODIMP raw_ExecuteComplete( LONG RecordsAffected, struct Error *pError, EventStatusEnum *adStatus, struct _Command *pCommand, struct _Recordset *pRecordset, struct _Connection *pConnection);
STDMETHODIMP raw_WillConnect(
BSTR *ConnectionString, BSTR *UserID, BSTR *Password, long *Options, EventStatusEnum *adStatus, struct _Connection *pConnection); STDMETHODIMP raw_ConnectComplete( struct Error *pError, EventStatusEnum *adStatus, struct _Connection *pConnection); STDMETHODIMP raw_Disconnect( EventStatusEnum *adStatus, struct _Connection *pConnection);};//-----The Recordset events----------------------------------------------class CRstEvent : public RecordsetEventsVt { private: ULONG m_cRef; public: CRstEvent() { m_cRef = 0; }; ~CRstEvent() {}; STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); STDMETHODIMP raw_WillChangeField( LONG cFields, VARIANT Fields, EventStatusEnum *adStatus, struct _Recordset *pRecordset); STDMETHODIMP raw_FieldChangeComplete( LONG cFields, VARIANT Fields, struct Error *pError, EventStatusEnum *adStatus, struct _Recordset *pRecordset); STDMETHODIMP raw_WillChangeRecord( EventReasonEnum adReason, LONG cRecords, EventStatusEnum *adStatus, struct _Recordset *pRecordset); STDMETHODIMP raw_RecordChangeComplete( EventReasonEnum adReason, LONG cRecords, struct Error *pError, EventStatusEnum *adStatus, struct _Recordset *pRecordset); STDMETHODIMP raw_WillChangeRecordset( EventReasonEnum adReason, EventStatusEnum *adStatus, struct _Recordset *pRecordset); STDMETHODIMP raw_RecordsetChangeComplete( EventReasonEnum adReason, struct Error *pError, EventStatusEnum *adStatus, struct _Recordset *pRecordset); STDMETHODIMP raw_WillMove( EventReasonEnum adReason, EventStatusEnum *adStatus, struct _Recordset *pRecordset); STDMETHODIMP raw_MoveComplete( EventReasonEnum adReason, struct Error *pError, EventStatusEnum *adStatus, struct _Recordset *pRecordset); STDMETHODIMP raw_EndOfRecordset( VARIANT_BOOL *fMoreData, EventStatusEnum *adStatus, struct _Recordset *pRecordset); STDMETHODIMP raw_FetchProgress( long Progress, long MaxProgress, EventStatusEnum *adStatus, struct _Recordset *pRecordset); STDMETHODIMP raw_FetchComplete( struct Error *pError, EventStatusEnum *adStatus, struct _Recordset *pRecordset);};//-----Implement each connection method---------------------------------- STDMETHODIMP CConnEvent::raw_InfoMessage( struct Error *pError, EventStatusEnum *adStatus, struct _Connection *pConnection) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CConnEvent::raw_BeginTransComplete( LONG TransactionLevel, struct Error *pError, EventStatusEnum *adStatus, struct _Connection *pConnection) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CConnEvent::raw_CommitTransComplete( struct Error *pError, EventStatusEnum *adStatus, struct _Connection *pConnection) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CConnEvent::raw_RollbackTransComplete( struct Error *pError, EventStatusEnum *adStatus, struct _Connection *pConnection) { *adStatus = adStatusUnwantedEvent; return S_OK; };
STDMETHODIMP CConnEvent::raw_WillExecute(
BSTR *Source, CursorTypeEnum *CursorType, LockTypeEnum *LockType, long *Options, EventStatusEnum *adStatus, struct _Command *pCommand, struct _Recordset *pRecordset, struct _Connection *pConnection) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CConnEvent::raw_ExecuteComplete( LONG RecordsAffected, struct Error *pError, EventStatusEnum *adStatus, struct _Command *pCommand, struct _Recordset *pRecordset, struct _Connection *pConnection) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CConnEvent::raw_WillConnect( BSTR *ConnectionString, BSTR *UserID, BSTR *Password, long *Options, EventStatusEnum *adStatus, struct _Connection *pConnection) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CConnEvent::raw_ConnectComplete( struct Error *pError, EventStatusEnum *adStatus, struct _Connection *pConnection) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CConnEvent::raw_Disconnect( EventStatusEnum *adStatus, struct _Connection *pConnection) { *adStatus = adStatusUnwantedEvent; return S_OK; };//-----Implement each recordset method----------------------------------- STDMETHODIMP CRstEvent::raw_WillChangeField( LONG cFields, VARIANT Fields, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CRstEvent::raw_FieldChangeComplete( LONG cFields, VARIANT Fields, struct Error *pError, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CRstEvent::raw_WillChangeRecord( EventReasonEnum adReason, LONG cRecords, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CRstEvent::raw_RecordChangeComplete( EventReasonEnum adReason, LONG cRecords, struct Error *pError, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CRstEvent::raw_WillChangeRecordset( EventReasonEnum adReason, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CRstEvent::raw_RecordsetChangeComplete( EventReasonEnum adReason, struct Error *pError, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CRstEvent::raw_WillMove( EventReasonEnum adReason, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CRstEvent::raw_MoveComplete( EventReasonEnum adReason, struct Error *pError, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CRstEvent::raw_EndOfRecordset( VARIANT_BOOL *fMoreData, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CRstEvent::raw_FetchProgress( long Progress, long MaxProgress, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; }; STDMETHODIMP CRstEvent::raw_FetchComplete( struct Error *pError, EventStatusEnum *adStatus, struct _Recordset *pRecordset) { *adStatus = adStatusUnwantedEvent; return S_OK; };//-----Implement QueryInterface, AddRef, and Release--------------------- STDMETHODIMP CRstEvent::QueryInterface(REFIID riid, void ** ppv) { *ppv = NULL; if (riid == __uuidof(IUnknown) || riid == __uuidof(RecordsetEventsVt)) *ppv = this; if (*ppv == NULL) return ResultFromScode(E_NOINTERFACE); AddRef(); return NOERROR; } STDMETHODIMP_(ULONG) CRstEvent::AddRef(void) { return ++m_cRef; }; STDMETHODIMP_(ULONG) CRstEvent::Release() { if (0 != --m_cRef) return m_cRef; delete this; return 0; } STDMETHODIMP CConnEvent::QueryInterface(REFIID riid, void ** ppv) { *ppv = NULL; if (riid == __uuidof(IUnknown) || riid == __uuidof(ConnectionEventsVt)) *ppv = this; if (*ppv == NULL) return ResultFromScode(E_NOINTERFACE); AddRef(); return NOERROR; } STDMETHODIMP_(ULONG) CConnEvent::AddRef() { return ++m_cRef; }; STDMETHODIMP_(ULONG) CConnEvent::Release() { if (0 != --m_cRef) return m_cRef; delete this; return 0; }//-----Write your main block of code-------------------------------------int main(int argc, char* argv[]){ HRESULT hr; DWORD dwConnEvt; DWORD dwRstEvt; IConnectionPointContainer *pCPC = NULL; IConnectionPoint *pCP = NULL; IUnknown *pUnk = NULL; CRstEvent *pRstEvent = NULL; CConnEvent *pConnEvent= NULL; int rc = 0; _RecordsetPtr pRst; _ConnectionPtr pConn; ::CoInitialize(NULL); hr = pConn.CreateInstance(__uuidof(Connection)); if (FAILED(hr)) return rc; hr = pRst.CreateInstance(__uuidof(Recordset)); if (FAILED(hr)) return rc; // Start using the Connection events hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer), (void **)&pCPC); if (FAILED(hr)) return rc; hr = pCPC->FindConnectionPoint(__uuidof(ConnectionEvents), &pCP); pCPC->Release(); if (FAILED(hr)) return rc; pConnEvent = new CConnEvent(); hr = pConnEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk); if (FAILED(hr)) return rc; hr = pCP->Advise(pUnk, &dwConnEvt); pCP->Release(); if (FAILED(hr)) return rc; // Start using the Recordset events hr = pRst->QueryInterface(__uuidof(IConnectionPointContainer), (void **)&pCPC); if (FAILED(hr)) return rc; hr = pCPC->FindConnectionPoint(__uuidof(RecordsetEvents), &pCP); pCPC->Release(); if (FAILED(hr)) return rc; pRstEvent = new CRstEvent(); hr = pRstEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk); if (FAILED(hr)) return rc; hr = pCP->Advise(pUnk, &dwRstEvt); pCP->Release(); if (FAILED(hr)) return rc; // Do some work pConn->Open("dsn=Pubs;", "sa", "", adConnectUnspecified); pRst->Open("SELECT * FROM authors", (IDispatch *) pConn, adOpenStatic, adLockReadOnly, adCmdText); pRst->MoveFirst(); while (pRst->EndOfFile == FALSE) { wprintf(L"Name = '%s'/n", (wchar_t*) ((_bstr_t) pRst->Fields->GetItem("au_lname")->Value)); pRst->MoveNext(); } pRst->Close(); pConn->Close(); // Stop using the Connection events hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer), (void **) &pCPC); if (FAILED(hr)) return rc; hr = pCPC->FindConnectionPoint(__uuidof(ConnectionEvents), &pCP); pCPC->Release(); if (FAILED(hr)) return rc; hr = pCP->Unadvise( dwConnEvt ); pCP->Release(); if (FAILED(hr)) return rc; // Stop using the Recordset events hr = pRst->QueryInterface(__uuidof(IConnectionPointContainer), (void **) &pCPC); if (FAILED(hr)) return rc; hr = pCPC->FindConnectionPoint(__uuidof(RecordsetEvents), &pCP); pCPC->Release(); if (FAILED(hr)) return rc; hr = pCP->Unadvise( dwRstEvt ); pCP->Release(); if (FAILED(hr)) return rc; CoUninitialize(); return 1;}