ADO イベントのインスタンス化: Visual C++
これは、Visual C++ で ADO イベントをインスタンス化する方法の概略的な説明です。 詳細については、「ADO イベント モデルの例 (VC++)」を参照してください。
ファイル adoint.h にある ConnectionEventsVt および RecordsetEventsVt インターフェイスから派生したクラスを作成します。
// 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
両方のクラスに各イベント ハンドラー メソッドを実装します。 各メソッドは単にS_OKの HRESULT を返すだけで十分です。 ただし、イベント ハンドラーが使用できることがわかっている場合は、既定で継続的に呼び出されます。 代わりに、最初の通知のみでそれ以降通知を受け取らないよう、adStatus を adStatusUnwantedEventに設定することをお勧めします。
// BeginEventExampleVC02
STDMETHODIMP CConnEvent::ConnectComplete(
ADOError *pError,
EventStatusEnum *adStatus,
_ADOConnection *pConnection)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
// EndEventExampleVC02
イベント クラスは IUnknown 継承するため、QueryInterface、AddRef、および Release メソッド 実装する必要もあります。 クラス コンストラクターとデストラクターも実装します。 タスクのこの部分を簡略化するのに最も快適な Visual C++ ツールを選択します。
イベントハンドラーを利用可能にするために、IConnectionPointContainer および IConnectionPoint インターフェイスの Recordset および Connection オブジェクトで QueryInterface を発行します。 その後、各クラス IConnectionPoint::Advise を発行します。
たとえば、イベント ハンドラーが使用可能であることを Recordset オブジェクトに正常に通知した場合、true を返すブール関数を使用しているとします。
// 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
この時点で、RecordsetEvent ファミリのイベントが有効になり、Recordset のイベントが発生すると、 メソッドが呼び出されます。
後で、イベント ハンドラーを使用できないようにする場合は、もう一度接続ポイントを取得し、IConnectionPoint::Unadvise メソッドを発行します。
// BeginEventExampleVC04
...
hr = pCP->Unadvise(dwEvtClass); //Turn off event support.
pCP->Release();
if (FAILED(hr)) return FALSE;
...
// EndEventExampleVC04
インターフェイスを解放し、必要に応じてクラス オブジェクトを破棄する必要があります。
次のコードは、Recordset イベント シンク クラスの完全な例を示しています。
// BeginEventExampleVC05.cpp
// compile with: /LD
#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;
}
};