« MS SQL日志文件长度过大的处理方法经典文章推荐:小论中英文网站的设计差异 »

不同语言的ADO事件实例

Visual Basic


在 Visual Basic 中有两种方法可以创建 ADO 事件实例。两种方法都有下列要求:首先,用 WithEvents 关键字声明的对象变量是类模块的一部分;其次,模块中的所有代码都可以访问对象。在第一个实例中,将创建一个事件对象和一个要处理的单独对象。(Form 对象是 Visual Basic 中的类。)

Dim WithEvents connEvent as Connection
Dim conn as New Connection

Private Sub MySub()
set connEvent = conn ' Enable event support.
conn.Open(...)
...
set connEvent = Nothing ' Disable event support.
...
End Sub

Private Sub connEvent_ConnectComplete(ByVal err as ADODB.Error, & _
adStatus as ADODB.EventStatus, ByVal pConnection as ADODB.Connection)
' Check the error object only if adStatus
' equals adStatusErrorsOccurred.
...
End Sub
第二个实例只使用单个的对象。

Dim WithEvents conn as New Connection

Private Sub MySub()
conn.Open(...)
...
set conn = Nothing ' Disable event support.
...
End Sub

Private Sub conn_ConnectComplete(ByVal err as ADODB.Error, & _
adStatus as ADODB.EventStatus, ByVal pConnection as ADODB.Connection)
' Check the error object only if adStatus
' equals adStatusErrorsOccurred.
...
End Sub

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

创建由 ConnectionEventsVt 和 RecordsetEventsVt 接口(在 adoint.h 文件中)派生的类。

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

在两个类中均实现每个事件处理程序方法。每个方法只需要返回一个 S_OK(类型为 HRESULT)。但是,一旦事件处理程序生效,在默认情况下,这些事件处理程序将被连续调用。为改变这种情况,您可以将 adStatus 设置为 adStatusUnwantedEvent,以便在第一次调用之后不再请求其他通知。

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

事件类从 Iunknown 继承,所以必须实现 QueryInterface、AddRef 和 Release 方法。还必须实现类构造函数和析构函数。选择最易于使用并可以简化这部分任务的 Visual C++ 工具。

在 Recordset 和 Connection 对象上对 IConnectionPointContainer 和 IConnectionPoint 接口发出 QueryInterface 之后,事件处理程序即可以使用。然后对每个类发出 IConnectionPoint::Advise。

例如,假设您正在使用 Boolean 函数,此函数在成功地向 Recordset 对象发出可以使用事件处理程序的通知时返回 True 值。

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); // Enable event support.
conn.open("DSN=Pubs");
conn.close();
conn.removeOnConnectComplete(handler); // Disable event support.
}
}

Microsoft Visual Basic Scripting Edition
VBScript 不支持事件。

原创文章如转载,请注明:转载自悠悠博客 [ http://www.ajaxstu.com/ ]

相关文章:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。