📄 speventq.h
字号:
/*******************************************************************************
* SPEventQ.h *
*------------*
* Description:
* This is the header file for the SAPI5 event queue implementation.
*-------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*******************************************************************************/
#ifndef SPEventQ_h
#define SPEventQ_h
#ifndef SPHelper_h
#include <SPHelper.h>
#endif
#ifndef SPCollec_h
#include <SPCollec.h>
#endif
//=== Inline helpers for copying and deleting events ============================
//=== Class definition ==========================================================
class CSpEventNode : public CSpEvent
{
public:
CSpEventNode * m_pNext;
static LONG Compare(const CSpEventNode * p1, const CSpEventNode *p2)
{
// Assumes offsets DO or DO NOT reset when stream number changes
if (p1->ulStreamNum < p2->ulStreamNum)
{
return -1;
}
else if (p1->ulStreamNum > p2->ulStreamNum)
{
return 1;
}
else if (p1->ullAudioStreamOffset < p2->ullAudioStreamOffset)
{
return -1;
}
else if (p1->ullAudioStreamOffset > p2->ullAudioStreamOffset)
{
return 1;
}
return 0;
}
};
typedef CSpBasicQueue<CSpEventNode, TRUE, TRUE> CSpEventList;
#define DECLARE_SPNOTIFYSOURCE_METHODS(T) \
STDMETHODIMP SetNotifySink(ISpNotifySink * pNotifySink) \
{ return T._SetNotifySink(pNotifySink); } \
STDMETHODIMP SetNotifyWindowMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) \
{ return T._SetNotifyWindowMessage(hWnd, Msg, wParam, lParam); } \
STDMETHODIMP SetNotifyCallbackFunction(SPNOTIFYCALLBACK * pfnCallback, WPARAM wParam, LPARAM lParam) \
{ return T._SetNotifyCallbackFunction(pfnCallback, wParam, lParam); } \
STDMETHODIMP SetNotifyCallbackInterface(ISpNotifyCallback * pSpCallback, WPARAM wParam, LPARAM lParam) \
{ return T._SetNotifyCallbackInterface(pSpCallback, wParam, lParam); } \
STDMETHODIMP SetNotifyWin32Event() \
{ return T._SetNotifyWin32Event(); } \
STDMETHODIMP WaitForNotifyEvent(DWORD dwMilliseconds) \
{ return T._WaitForNotifyEvent(dwMilliseconds); } \
STDMETHODIMP_(HANDLE) GetNotifyEventHandle() \
{ return T._GetNotifyEventHandle(); }
#define DECLARE_SPEVENTSOURCE_METHODS(T) \
DECLARE_SPNOTIFYSOURCE_METHODS(T) \
STDMETHODIMP SetInterest(ULONGLONG ullEventInterest, ULONGLONG ullQueuedInterest) \
{ return T._SetInterest(ullEventInterest, ullQueuedInterest); } \
STDMETHODIMP GetEvents(ULONG ulCount, SPEVENT* pEventArray, ULONG * pulFetched) \
{ return T._GetEvents(ulCount, pEventArray, pulFetched); } \
STDMETHODIMP GetInfo(SPEVENTSOURCEINFO *pInfo) \
{ return T._GetInfo(pInfo); }
class CSpEventSource
{
public:
CSpEventSource(CComObjectRootEx<CComMultiThreadModel> * pParent) :
m_pParent(pParent)
{
m_ullEventInterest = 0; m_ullQueuedInterest = 0;
m_ulStreamNum = 0;
}
HRESULT _SetNotifySink(ISpNotifySink * pNotifySink);
HRESULT _SetNotifyWindowMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
HRESULT _SetNotifyCallbackFunction(SPNOTIFYCALLBACK * pfnCallback, WPARAM wParam, LPARAM lParam);
HRESULT _SetNotifyCallbackInterface(ISpNotifyCallback * pSpCallback, WPARAM wParam, LPARAM lParam);
HRESULT _SetNotifyWin32Event();
HRESULT _WaitForNotifyEvent(DWORD dwMilliseconds);
HANDLE _GetNotifyEventHandle();
HRESULT _SetInterest(ULONGLONG ullEventInterest , ULONGLONG ullQueuedInterest);
HRESULT _GetEvents( ULONG ulCount, SPEVENT* pEventArray, ULONG * pulFetched );
HRESULT _GetInfo(SPEVENTSOURCEINFO *pInfo );
/*--- Non interface methods ---*/
HRESULT _CompleteEvents( ULONGLONG ullPos = 0xFFFFFFFFFFFFFFFF );
inline void _MoveAllToFreeList(CSpEventList * pList);
inline void _RemoveAllEvents();
inline HRESULT _AddEvent(const SPEVENT & Event);
inline HRESULT _AddEvents(const SPEVENT* pEventArray, ULONG ulCount);
inline HRESULT _DeserializeAndAddEvent(const BYTE * pBuffer, ULONG * pcbUsed);
inline HRESULT _GetStreamNumber(const ULONGLONG ullAudioOffset, ULONG *pulStreamNum);
//=== Data members ==============================
public:
ULONGLONG m_ullEventInterest;
ULONGLONG m_ullQueuedInterest;
ULONG m_ulStreamNum;
CSpEventList m_PendingList;
CSpEventList m_CompletedList;
CSpEventList m_FreeList;
CComPtr<ISpNotifySink> m_cpNotifySink;
CComPtr<ISpNotifyTranslator> m_cpEventTranslator; // If non-NULL then Win32 events being used
CComObjectRootEx<CComMultiThreadModel> * m_pParent;
CComAutoCriticalSection m_NotifyObjChangeCrit; // Critical section used to make sure that
// the notify object (m_cpNotifySink) not changed
// while waiting on it.
};
//
//=== Inlines =========================================================
//
//
// WARNING: If this logic changes, you will need to change the logic in SetNotifyWin32Event also.
//
inline HRESULT CSpEventSource::_SetNotifySink(ISpNotifySink * pNotifySink)
{
if (SP_IS_BAD_OPTIONAL_INTERFACE_PTR(pNotifySink))
{
return E_INVALIDARG;
}
else
{
m_pParent->Lock();
m_NotifyObjChangeCrit.Lock();
m_cpEventTranslator.Release();
m_cpNotifySink = pNotifySink;
if (m_cpNotifySink && m_CompletedList.GetHead())
{
m_cpNotifySink->Notify();
}
m_NotifyObjChangeCrit.Unlock();
m_pParent->Unlock();
return S_OK;
}
}
/****************************************************************************
* CSpEventSource::_SetNotifyWindowMessage *
*-----------------------------------------*
* Description:
*
* Returns:
*
********************************************************************* RAL ***/
inline HRESULT CSpEventSource::_SetNotifyWindowMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
SPDBG_FUNC("CSpEventSource::_SetNotifyWindowMessage");
HRESULT hr = S_OK;
CComPtr<ISpNotifyTranslator> cpTranslator;
hr = cpTranslator.CoCreateInstance(CLSID_SpNotifyTranslator);
if (SUCCEEDED(hr))
{
hr = cpTranslator->InitWindowMessage(hWnd, Msg, wParam, lParam);
}
if (SUCCEEDED(hr))
{
hr = _SetNotifySink(cpTranslator);
}
return hr;
}
/****************************************************************************
* CSpEventSource::_SetNotifyCallbackFunction *
*--------------------------------------------*
* Description:
*
* Returns:
*
********************************************************************* RAL ***/
inline HRESULT CSpEventSource::_SetNotifyCallbackFunction(SPNOTIFYCALLBACK * pfnCallback, WPARAM wParam, LPARAM lParam)
{
SPDBG_FUNC("CSpEventSource::_SetNotifyCallbackFunction");
HRESULT hr = S_OK;
CComPtr<ISpNotifyTranslator> cpTranslator;
hr = cpTranslator.CoCreateInstance(CLSID_SpNotifyTranslator);
if (SUCCEEDED(hr))
{
hr = cpTranslator->InitCallback(pfnCallback, wParam, lParam);
}
if (SUCCEEDED(hr))
{
hr = _SetNotifySink(cpTranslator);
}
return hr;
}
/****************************************************************************
* CSpEventSource::_SetNotifyCallbackInterface *
*---------------------------------------------*
* Description:
*
* Returns:
*
********************************************************************* RAL ***/
inline HRESULT CSpEventSource::_SetNotifyCallbackInterface(ISpNotifyCallback * pSpCallback, WPARAM wParam, LPARAM lParam)
{
SPDBG_FUNC("CSpEventSource::_SetNotifyCallbackInterface");
HRESULT hr = S_OK;
CComPtr<ISpNotifyTranslator> cpTranslator;
hr = cpTranslator.CoCreateInstance(CLSID_SpNotifyTranslator);
if (SUCCEEDED(hr))
{
hr = cpTranslator->InitSpNotifyCallback(pSpCallback, wParam, lParam);
}
if (SUCCEEDED(hr))
{
hr = _SetNotifySink(cpTranslator);
}
return hr;
}
/****************************************************************************
* CSpEventSource::_SetNotifyWin32Event *
*--------------------------------------*
* Description:
*
* Returns:
*
********************************************************************* RAL ***/
inline HRESULT CSpEventSource::_SetNotifyWin32Event(void)
{
SPDBG_FUNC("CSpEventSource::_SetNotifyWin32Event");
HRESULT hr = S_OK;
CComPtr<ISpNotifyTranslator> cpTranslator;
hr = cpTranslator.CoCreateInstance(CLSID_SpNotifyTranslator);
if (SUCCEEDED(hr))
{
hr = cpTranslator->InitWin32Event(NULL, TRUE);
}
if (SUCCEEDED(hr))
{
//
// In this case we do NOT call _SetNotify sink since we want to set the cpEventTranslator
//
m_pParent->Lock();
m_NotifyObjChangeCrit.Lock();
m_cpEventTranslator = cpTranslator;
m_cpNotifySink = cpTranslator;
if (m_cpNotifySink && m_CompletedList.GetHead())
{
m_cpNotifySink->Notify();
}
m_NotifyObjChangeCrit.Unlock();
m_pParent->Unlock();
}
return hr;
}
/****************************************************************************
* CSpEventSource::_WaitForNotifyEvent *
*-------------------------------------*
* Description:
*
* Returns:
*
********************************************************************* RAL ***/
inline HRESULT CSpEventSource::_WaitForNotifyEvent(DWORD dwMilliseconds)
{
SPDBG_FUNC("CSpEventSource::_WaitForNotifyEvent");
HRESULT hr = S_OK;
m_NotifyObjChangeCrit.Lock();
if (m_cpEventTranslator)
{
hr = m_cpEventTranslator->Wait(dwMilliseconds);
}
else
{
if (m_cpNotifySink)
{
hr = SPERR_ALREADY_INITIALIZED;
}
else
{
hr = _SetNotifyWin32Event();
if (SUCCEEDED(hr))
{
hr = m_cpEventTranslator->Wait(dwMilliseconds);
}
}
}
m_NotifyObjChangeCrit.Unlock();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -