172 lines
4.3 KiB
C++
172 lines
4.3 KiB
C++
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1996 - 1999.
|
||
|
//
|
||
|
// File: watch.hxx
|
||
|
//
|
||
|
// Contents:
|
||
|
//
|
||
|
// History: 15 Aug 1996 DLee Created
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <ocidl.h>
|
||
|
|
||
|
const unsigned cmsNotifySpacing = 1000;
|
||
|
const unsigned cmsStartSpacing = 100;
|
||
|
const unsigned cmsBackoff = 100;
|
||
|
const unsigned cmsSleep = 50;
|
||
|
|
||
|
class CRowsetNotifyWatch : public IRowsetWatchNotify
|
||
|
{
|
||
|
public:
|
||
|
CRowsetNotifyWatch(HWND hwnd) :
|
||
|
_cRef(1),
|
||
|
_hwndNotify(hwnd),
|
||
|
_cmsTicks(GetTickCount() + cmsNotifySpacing),
|
||
|
_cmsSpacing( cmsStartSpacing ),
|
||
|
_fHoldNotifications( FALSE ),
|
||
|
_fIgnore( FALSE ),
|
||
|
_wnLast( 0 )
|
||
|
{
|
||
|
srchDebugOut((DEB_TRACE,"CRowsetNotifyWatch::Construct\n"));
|
||
|
}
|
||
|
|
||
|
~CRowsetNotifyWatch()
|
||
|
{
|
||
|
srchDebugOut((DEB_TRACE,"CRowsetNotifyWatch::~\n"));
|
||
|
}
|
||
|
|
||
|
// IUnknown methods.
|
||
|
|
||
|
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppiuk)
|
||
|
{
|
||
|
srchDebugOut((DEB_TRACE,"CRowsetNotifyWatch::QI\n"));
|
||
|
*ppiuk = (void **) this; // hold our breath and jump
|
||
|
AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHOD_(ULONG, AddRef) (THIS)
|
||
|
{
|
||
|
srchDebugOut((DEB_TRACE,"CRowsetNotifyWatch::AddRef\n"));
|
||
|
return ++_cRef;
|
||
|
}
|
||
|
|
||
|
STDMETHOD_(ULONG, Release) (THIS)
|
||
|
{
|
||
|
srchDebugOut((DEB_TRACE,"CRowsetNotifyWatch::Release\n"));
|
||
|
ULONG tmp = --_cRef;
|
||
|
|
||
|
if ( 0 == _cRef )
|
||
|
delete this;
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
// IRowsetNotifyWatch method
|
||
|
|
||
|
STDMETHOD( OnChange) (THIS_ IRowset* pRowset, DBWATCHNOTIFY changeType)
|
||
|
{
|
||
|
AddRef();
|
||
|
srchDebugOut((DEB_TRACE,"CRowsetNotifyWatch::OnChange Top\n"));
|
||
|
|
||
|
if ( DBWATCHNOTIFY_QUERYDONE != changeType )
|
||
|
{
|
||
|
while ( ( _fHoldNotifications ) ||
|
||
|
( ( GetTickCount() - _cmsTicks ) < _cmsSpacing ) )
|
||
|
{
|
||
|
if ( ( _fIgnore ) ||
|
||
|
( 1 == _cRef ) ) // did we die in our sleep?
|
||
|
break;
|
||
|
|
||
|
Sleep( cmsSleep );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( ( !_fIgnore ) &&
|
||
|
( _cRef > 1 ) ) // did we (the query) die in our sleep?
|
||
|
{
|
||
|
_wnLast = changeType;
|
||
|
PostMessage( _hwndNotify,
|
||
|
wmNotification,
|
||
|
changeType,
|
||
|
(LPARAM) pRowset );
|
||
|
|
||
|
_cmsTicks = GetTickCount();
|
||
|
_cmsSpacing = __min( cmsNotifySpacing,
|
||
|
cmsBackoff + _cmsSpacing );
|
||
|
srchDebugOut(( DEB_TRACE, "CRowsetNotifyWatch::OnChange Blasted\n" ));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
srchDebugOut((DEB_TRACE,"CRowsetNotifyWatch::OnChange die\n"));
|
||
|
}
|
||
|
|
||
|
Release();
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
// private methods
|
||
|
|
||
|
void HoldNotifications( BOOL f )
|
||
|
{
|
||
|
_fHoldNotifications = f;
|
||
|
_cmsTicks = GetTickCount();
|
||
|
}
|
||
|
|
||
|
void IgnoreNotifications( BOOL fIgnore )
|
||
|
{ _fIgnore = fIgnore; }
|
||
|
|
||
|
private:
|
||
|
ULONG _cRef;
|
||
|
HWND _hwndNotify;
|
||
|
ULONG _cmsTicks;
|
||
|
ULONG _cmsSpacing;
|
||
|
BOOL _fHoldNotifications;
|
||
|
BOOL _fIgnore;
|
||
|
DBWATCHNOTIFY _wnLast;
|
||
|
};
|
||
|
|
||
|
class CSearchQuery;
|
||
|
class CBookMark;
|
||
|
|
||
|
class CWatchQuery
|
||
|
{
|
||
|
public:
|
||
|
CWatchQuery (CSearchQuery* pSearch, IRowsetScroll* pRowset);
|
||
|
~CWatchQuery ();
|
||
|
BOOL Ok () const { return _pRowsetWatch != 0; }
|
||
|
|
||
|
void Notify (HWND hwndList, DBWATCHNOTIFY changeType);
|
||
|
void NotifyComplete();
|
||
|
void RowsChanged (HWND hwnd);
|
||
|
void Extend (HWATCHREGION hRegion);
|
||
|
void Move (HWATCHREGION hRegion);
|
||
|
void Shrink (HWATCHREGION hRegion, CBookMark& bmk, ULONG cRows);
|
||
|
HWATCHREGION Handle() { return _hRegion; }
|
||
|
|
||
|
void IgnoreNotifications( BOOL fIgnore )
|
||
|
{ _pNotifyWatch->IgnoreNotifications( fIgnore ); }
|
||
|
|
||
|
private:
|
||
|
void ExecuteScript (HWND hwndList, ULONG cChanges, DBROWWATCHCHANGE* aScript);
|
||
|
|
||
|
CSearchQuery* _pClient;
|
||
|
BOOL _fEverGotARowsChanged;
|
||
|
DBWATCHNOTIFY _wnLast;
|
||
|
|
||
|
IConnectionPointContainer *_pContainer;
|
||
|
IConnectionPoint * _pPoint;
|
||
|
DWORD _dwAdviseID;
|
||
|
|
||
|
CRowsetNotifyWatch * _pNotifyWatch;
|
||
|
IRowsetWatchRegion* _pRowsetWatch;
|
||
|
HWATCHREGION _hRegion;
|
||
|
DWORD _mode;
|
||
|
};
|
||
|
|