windows-nt/Source/XPSP1/NT/inetsrv/query/apps/srch/watch.hxx
2020-09-26 16:20:57 +08:00

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