不同语言的 ADO 事件实例

不同的编程语言以不同的方式创建 ADO 事件实例。如下所有范例均创建 ConnectComplete 事件处理程序。

Visual Basic

Dim WithEvent connEvent as Connection
Dim conn as New Connection
set connEvent = conn      '打开事件支持。
conn.Open(...)
...
set connEvent = Nothing   '关闭事件支持。
...
Private Sub connEvent_ConnectComplete(ByVal err as ADODB.Error, & _
adStatus as ADODB.EventStatus, ByVal pConnectionas ADODB.Connection)
'仅当 adStatus 等于 adStatusErrorsOccurred 时检查错误对象。
...
End Sub

Visual C++

这是关于在 VC++ 中如何实例化事件的示意性说明。

创建在 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);
...
}

在两个类中执行每个事件处理程序方法。每个方法只返回一个 HRESULT of S_OK 就够了。但是,一旦事件处理程序有效,这些事件处理程序就会在默认状态下被连续调用。为改变这种情况,您可通过将 adStatus 设置为 adStatusUnwantedEvent,以便在第一次调用之后不再请求其他通知。

STDMETHODIMP CConnEvent::ConnectComplete(
            ADOError *pError,
            EventStatusEnum *adStatus,
             _ADOConnection *pConnection) 
      {
      *adStatus = adStatusUnwantedEvent;
      return S_OK;
      }

事件类继承了 Iunknown,所以也必须执行 QueryInterfaceAddRef Release 方法。如要执行类构造函数和析构函数,请选择最易于使用并能简化这部分任务的 VC++ 工具。

通过在 Recordset Connection 对象上向 IConnectionPointContainer IConnectionPoint 接口发出 QueryInterface,通知事件处理程序现在已可以使用,然后向各类发出 IConnectionPoint::Advise

例如,假设您正在使用布尔型函数,该函数在成功地向 Recordset 对象发出可以使用事件处理程序的通知时返回“真”值。

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 类的事件会被打开并且在 Recordset 事件出现时方法将被调用。

此后,如果您想使事件处理程序无效,可以再次获取连接点并发出 IConnectionPoint::UnAdvise 方法。

...
hr = pCP->UnAdvise(dwEvtClass);   //Turn off event support.
pCP->Release();
if (FAILED(hr)) return FALSE;
...

当然,必须在适当的时候释放接口并毁掉类的对象。

Visual J++

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);   //关闭事件支持。
}
}

VBScript

VBScript 不支持事件。