不同的編程語言以不同的方式創(chuàng)建 ADO 事件實(shí)例。如下所有范例均創(chuàng)建 ConnectComplete 事件處理程序。
Dim WithEvent connEvent as Connection
Dim conn as New Connection
set connEvent = conn '打開事件支持。
conn.Open(...)
...
set connEvent = Nothing '關(guān)閉事件支持。
...
Private Sub connEvent_ConnectComplete(ByVal err as ADODB.Error, & _
adStatus as ADODB.EventStatus, ByVal pConnectionas ADODB.Connection)
'僅當(dāng) adStatus 等于 adStatusErrorsOccurred 時(shí)檢查錯(cuò)誤對(duì)象。
...
End Sub
這是關(guān)于在 VC++ 中如何實(shí)例化事件的示意性說明。
創(chuàng)建在 adoint.h 文件中由 ConnectionEventsVt 和 RecordsetEventsVt 接口所派生的類。
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);
...
}
在兩個(gè)類中執(zhí)行每個(gè)事件處理程序方法。每個(gè)方法只返回一個(gè) HRESULT of S_OK 就夠了。但是,一旦事件處理程序有效,這些事件處理程序就會(huì)在默認(rèn)狀態(tài)下被連續(xù)調(diào)用。為改變這種情況,您可通過將 adStatus 設(shè)置為 adStatusUnwantedEvent,以便在第一次調(diào)用之后不再請(qǐng)求其他通知。
STDMETHODIMP CConnEvent::ConnectComplete(
ADOError *pError,
EventStatusEnum *adStatus,
_ADOConnection *pConnection)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
}
事件類繼承了 Iunknown,所以也必須執(zhí)行 QueryInterface、AddRef 和 Release 方法。如要執(zhí)行類構(gòu)造函數(shù)和析構(gòu)函數(shù),請(qǐng)選擇最易于使用并能簡化這部分任務(wù)的 VC++ 工具。
通過在 Recordset 和 Connection 對(duì)象上向 IConnectionPointContainer 和 IConnectionPoint 接口發(fā)出 QueryInterface,通知事件處理程序現(xiàn)在已可以使用,然后向各類發(fā)出 IConnectionPoint::Advise。
例如,假設(shè)您正在使用布爾型函數(shù),該函數(shù)在成功地向 Recordset 對(duì)象發(fā)出可以使用事件處理程序的通知時(shí)返回“真”值。
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, &pCPC);
if (FAILED(hr)) return FALSE;
hr = pCPC->FindConnectionPoint(IID_ADORecordsetEvents, &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;
...
在此,RecordsetEvent 類的事件會(huì)被打開并且在 Recordset 事件出現(xiàn)時(shí)方法將被調(diào)用。
此后,如果您想使事件處理程序無效,可以再次獲取連接點(diǎn)并發(fā)出 IConnectionPoint::UnAdvise 方法。
...
hr = pCP->UnAdvise(dwEvtClass); //Turn off event support.
pCP->Release();
if (FAILED(hr)) return FALSE;
...
當(dāng)然,必須在適當(dāng)?shù)臅r(shí)候釋放接口并毀掉類的對(duì)象。
import wfc.data.*;
public class MyClass
{
ConnectionEventHandler handler =
new ConnectionEventHandler(this,"onConnectComplete");
public void onConnectComplete(Object sender,ConnectionEvent e)
{
if (e.adStatus == AdoEnums.EventStatus.ERRORSOCCURRED)
System.out.println("Connection failed");
else
System.out.println("Connection completed");
return;
}
void main( void )
{
Connection conn = new Connection();
conn.addOnConnectComplete(handler); //打開事件支持。
conn.open("DSN=pubs");
conn.close();
conn.removeOnConnectComplete(handler); //關(guān)閉事件支持。
}
}
VBScript 不支持事件。