217 lines
6.4 KiB
C++
217 lines
6.4 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1994 - 1998.
|
|
//
|
|
// File: rownotfy.hxx
|
|
//
|
|
// Contents: Rowset notification connection points
|
|
//
|
|
// Classes: CRowsetNotification
|
|
// CRowsetAsynchNotification
|
|
//
|
|
// History: 16 Feb 1998 AlanW Created from conpt.hxx
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include <conpt.hxx>
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Class: CRowsetNotification
|
|
//
|
|
// Purpose: Implements IConnectionPoint for IRowsetNotify
|
|
//
|
|
// Interface: IConnectionPoint
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
class CRowsetNotification : public CConnectionPointBase
|
|
{
|
|
public:
|
|
|
|
CRowsetNotification ( ) :
|
|
CConnectionPointBase( IID_IRowsetNotify )
|
|
{
|
|
}
|
|
|
|
//
|
|
// IRowsetNotify methods.
|
|
//
|
|
|
|
STDMETHOD(OnFieldChange) ( IRowset * pRowset,
|
|
HROW hRow,
|
|
DBORDINAL cColumns,
|
|
DBORDINAL rgColumns[],
|
|
DBREASON eReason,
|
|
DBEVENTPHASE ePhase,
|
|
BOOL fCantDeny );
|
|
|
|
STDMETHOD(OnRowChange) ( IRowset * pRowset,
|
|
DBCOUNTITEM cRows,
|
|
const HROW rghRows[],
|
|
DBREASON eReason,
|
|
DBEVENTPHASE ePhase,
|
|
BOOL fCantDeny );
|
|
|
|
STDMETHOD(OnRowsetChange) ( IRowset * pRowset,
|
|
DBREASON eReason,
|
|
DBEVENTPHASE ePhase,
|
|
BOOL fCantDeny );
|
|
|
|
//
|
|
// Connection point management
|
|
//
|
|
virtual void AddConnectionPoints(CConnectionPointContainer * pCPC)
|
|
{
|
|
SetContainer( pCPC );
|
|
pCPC->AddConnectionPoint( _iidSink, this );
|
|
}
|
|
|
|
virtual void StopNotifications(void)
|
|
{
|
|
Disconnect();
|
|
}
|
|
|
|
BOOL IsNotifyActive(void)
|
|
{
|
|
return GetAdviseCount() != 0;
|
|
}
|
|
|
|
private:
|
|
|
|
BOOL DoRowsetChangeCallout ( CEnumConnectionsLite & Enum,
|
|
IRowset * pRowset,
|
|
DBREASON eReason,
|
|
DBEVENTPHASE ePhase,
|
|
BOOL fCantDeny );
|
|
|
|
};
|
|
|
|
|
|
class PQuery;
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Class: CRowsetAsynchNotification
|
|
//
|
|
// Purpose: Implements IConnectionPoint for IRowsetNotify, IDBAsynchNotify,
|
|
// IRowsetWatchNotify
|
|
//
|
|
// Interface: IConnectionPoint
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
class CRowsetAsynchNotification : public CRowsetNotification
|
|
{
|
|
public:
|
|
|
|
// Sleep timeouts, in msec.
|
|
enum {
|
|
defNotificationSleepDuration = 100,
|
|
#if CIDBG == 1 // for checked builds, allow a longer timeout for stress
|
|
defNotifyThreadTerminateTimeout = 60000
|
|
#else
|
|
defNotifyThreadTerminateTimeout = 10000
|
|
#endif
|
|
};
|
|
|
|
CRowsetAsynchNotification (PQuery & query,
|
|
ULONG hCursor,
|
|
IRowset * pRowset,
|
|
CCIOleDBError & ErrorObject,
|
|
BOOL fWatch);
|
|
|
|
~CRowsetAsynchNotification ( );
|
|
|
|
STDMETHOD_(ULONG, AddRef) (THIS);
|
|
|
|
STDMETHOD_(ULONG, Release) (THIS);
|
|
|
|
//
|
|
// Connection point management
|
|
//
|
|
inline void AddConnectionPoints(CConnectionPointContainer * pCPC);
|
|
|
|
void StopNotifications(void);
|
|
|
|
private:
|
|
static DWORD _NotifyThread( CRowsetAsynchNotification *self );
|
|
DWORD _DoNotifications(void);
|
|
|
|
BOOL _DoAsynchNotification(void);
|
|
BOOL _DoWatchNotification(void);
|
|
|
|
void _StartNotifyThread(void);
|
|
void _EndNotifyThread(void);
|
|
|
|
static void AdviseHelper( PVOID pHelperConext,
|
|
CConnectionPointBase * pConnPt,
|
|
CConnectionContext * pConnCtx );
|
|
static void UnadviseHelper( PVOID pHelperConext,
|
|
CConnectionPointBase * pConnPt,
|
|
CConnectionContext * pConnCtx,
|
|
CReleasableLock & lock );
|
|
|
|
BOOL _fDoWatch; // if TRUE, do watch notification
|
|
BOOL _fPopulationComplete; // if TRUE, rowset population is done
|
|
ULONG _cAdvise; // number of active advises
|
|
|
|
CConnectionPointBase _AsynchConnectionPoint;
|
|
CConnectionPointBase _WatchConnectionPoint;
|
|
|
|
PQuery & _query;
|
|
ULONG _hCursor; // A handle to the table cursor
|
|
|
|
IRowset * const _pRowset;
|
|
|
|
HANDLE _threadNotify;
|
|
DWORD _threadNotifyId;
|
|
CEventSem _evtEndNotifyThread;
|
|
};
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CRowsetAsynchNotification::AddConnectionPoints, public
|
|
//
|
|
// Synopsis: Sets up linkages between the connection point container
|
|
// and all the connection points
|
|
//
|
|
// Arguments: [pCPC] - a pointer to the connection point container
|
|
//
|
|
// History: 16 Feb 1998 Alanw
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
void CRowsetAsynchNotification::AddConnectionPoints(
|
|
CConnectionPointContainer * pCPC)
|
|
{
|
|
CRowsetNotification::SetContainer( pCPC );
|
|
pCPC->AddConnectionPoint( _iidSink, (CRowsetNotification* )this );
|
|
|
|
_AsynchConnectionPoint.SetContainer( pCPC );
|
|
_AsynchConnectionPoint.SetAdviseHelper( &AdviseHelper, this );
|
|
_AsynchConnectionPoint.SetUnadviseHelper( &UnadviseHelper, this );
|
|
pCPC->AddConnectionPoint( IID_IDBAsynchNotify,
|
|
&_AsynchConnectionPoint );
|
|
|
|
if ( _fDoWatch )
|
|
{
|
|
_WatchConnectionPoint.SetContainer( pCPC );
|
|
_WatchConnectionPoint.SetAdviseHelper( &AdviseHelper, this );
|
|
_WatchConnectionPoint.SetUnadviseHelper( &UnadviseHelper, this );
|
|
pCPC->AddConnectionPoint( IID_IRowsetWatchNotify,
|
|
&_WatchConnectionPoint );
|
|
}
|
|
}
|
|
|