Visual C++
Gilt für: Access 2013, Office 2013
Dies ist eine schematische Beschreibung, wie ADO-Ereignisse in Microsoft Visual C++ instanziiert werden. Eine vollständige Beschreibung finden Sie unter Beispiel für das ADO-Ereignismodell (VC++).
Create classes derived from the ConnectionEventsVt and RecordsetEventsVt interfaces found in the file adoint.h.
// BeginEventExampleVC01
class CConnEvent : public ConnectionEventsVt
{
public:
STDMETHODIMP InfoMessage(
ADOError *pError,
EventStatusEnum *adStatus,
_ADOConnection *pConnection);
...
}
class CRstEvent : public RecordsetEventsVt
{
public:
STDMETHODIMP WillChangeField(
LONG cFields,
VARIANT Fields,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset);
...
}
// EndEventExampleVC01
Implementieren Sie alle Ereignishandlermethoden in beiden Klassen. Es reicht aus, wenn jede Methode lediglich S_OK für HRESULT zurückgibt. Wenn Sie allerdings bekannt geben, dass Ihre Ereignishandler verfügbar sind, werden sie standardmäßig kontinuierlich aufgerufen. Stattdessen sollten möglicherweise nach dem ersten Mal keine weitere Benachrichtigung mehr angefordert werden, indem Sie adStatus auf adStatusUnwantedEvent festlegen.
// BeginEventExampleVC02
STDMETHODIMP CConnEvent::ConnectComplete(
ADOError *pError,
EventStatusEnum *adStatus,
_ADOConnection *pConnection)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
// EndEventExampleVC02
Die Ereignisklassen erben von IUnknown, weshalb Sie auch die Methoden QueryInterface, AddRef und Release implementieren müssen. Implementieren Sie auch Klassenkonstruktoren und -destruktoren. Wählen Sie die Visual C++-Tools, die Ihnen am vertrautesten sind, um diesen Schritt zu vereinfachen.
Teilen Sie mit, dass Ihre Ereignishandler verfügbar sind, indem Sie QueryInterface in den Recordset- und Connection-Objekten für die Schnittstellen IConnectionPointContainer und IConnectionPoint ausstellen. Stellen Sie anschließend IConnectionPoint::Advise für jede Klasse aus.
Angenommen, Sie verwenden eine boolesche Funktion, die True zurückgibt, wenn ein Recordset -Objekt erfolgreich informiert wird, dass Ereignishandler verfügbar sind.
// BeginEventExampleVC03
HRESULT hr;
DWORD dwEvtClass;
IConnectionPointContainer *pCPC = NULL;
IConnectionPoint *pCP = NULL;
CRstEvent *pRStEvent = NULL;
...
_RecordsetPtr pRs;
pRs.CreateInstance(__uuidof(Recordset));
pRStEvent = new CRstEvent;
if (pRStEvent == NULL) return FALSE;
...
hr = pRs->QueryInterface(IID_IConnectionPointContainer, (LPVOID *)&pCPC);
if (FAILED(hr)) return FALSE;
hr = pCPC->FindConnectionPoint(RecordsetEvents, &pCP);
pCPC->Release(); // Always Release now, even before checking.
if (FAILED(hr)) return FALSE;
hr = pCP->Advise(pRstEvent, &dwEvtClass); //Turn on event support.
pCP->Release();
if (FAILED(hr)) return FALSE;
...
return TRUE;
...
// EndEventExampleVC03
Nun sind Ereignisse für die RecordsetEvent -Familie aktiviert, und Ihre Methoden werden aufgerufen, wenn Recordset -Ereignisse auftreten.
Wenn später die Ereignishandler nicht mehr verfügbar sein sollen, rufen Sie den Verbindungspunkt erneut ab, und stellen Sie die IConnectionPoint::Unadvise -Methode aus.
// BeginEventExampleVC04
...
hr = pCP->Unadvise(dwEvtClass); //Turn off event support.
pCP->Release();
if (FAILED(hr)) return FALSE;
...
// EndEventExampleVC04
Sie müssen Schnittstellen freigeben und entsprechende Klassenobjekte zerstören.
Der folgende Code zeigt ein vollständiges Beispiel für eine Recordset -Ereignissenkenklasse.
// BeginEventExampleVC05
#include <adoint.h>
class CADORecordsetEvents : public RecordsetEventsVt
{
public :
ULONG m_ulRefCount;
CADORecordsetEvents():m_ulRefCount(1){}
STDMETHOD(QueryInterface)(REFIID iid, LPVOID * ppvObject)
{
if (IsEqualIID(__uuidof(IUnknown), iid) ||
IsEqualIID(__uuidof(RecordsetEventsVt), iid))
{
*ppvObject = this;
return S_OK;
}
else
return E_NOINTERFACE;
}
STDMETHOD_(ULONG, AddRef)()
{
return m_ulRefCount++;
}
STDMETHOD_(ULONG, Release)()
{
if (--m_ulRefCount == 0)
{
delete this;
return 0;
}
else
return m_ulRefCount;
}
STDMETHOD(WillChangeField)(
LONG cFields,
VARIANT Fields,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
STDMETHOD(FieldChangeComplete)(
LONG cFields,
VARIANT Fields,
ADOError *pError,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
STDMETHOD(WillChangeRecord)(
EventReasonEnum adReason,
LONG cRecords,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
STDMETHOD(RecordChangeComplete)(
EventReasonEnum adReason,
LONG cRecords,
ADOError *pError,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
STDMETHOD(WillChangeRecordset)(
EventReasonEnum adReason,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
STDMETHOD(RecordsetChangeComplete)(
EventReasonEnum adReason,
ADOError *pError,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
STDMETHOD(WillMove)(
EventReasonEnum adReason,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
STDMETHOD(MoveComplete)(
EventReasonEnum adReason,
ADOError *pError,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
STDMETHOD(EndOfRecordset)(
VARIANT_BOOL *fMoreData,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
STDMETHOD(FetchProgress)(
long Progress,
long MaxProgress,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
STDMETHOD(FetchComplete)(
ADOError *pError,
EventStatusEnum *adStatus,
_ADORecordset *pRecordset)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
};
// EndEventExampleVC05