📄 sphelper.h
字号:
return E_POINTER;
}
return CopyTo(pFormatId, ppCoMemWFEX);
}
BOOL operator==(const CSpStreamFormat & Other) const
{
return IsEqual(Other.m_guidFormatId, Other.m_pCoMemWaveFormatEx);
}
BOOL operator!=(const CSpStreamFormat & Other) const
{
return !IsEqual(Other.m_guidFormatId, Other.m_pCoMemWaveFormatEx);
}
ULONG SerializeSize() const
{
ULONG cb = sizeof(ULONG) + sizeof(m_guidFormatId);
if (m_pCoMemWaveFormatEx)
{
cb += sizeof(WAVEFORMATEX) + m_pCoMemWaveFormatEx->cbSize + 3; // Add 3 to round up
cb -= cb % 4; // Round to DWORD
}
return cb;
}
ULONG Serialize(BYTE * pBuffer) const
{
ULONG cb = SerializeSize();
*((UNALIGNED ULONG *)pBuffer) = cb;
pBuffer += sizeof(ULONG);
*((UNALIGNED GUID *)pBuffer) = m_guidFormatId;
if (m_pCoMemWaveFormatEx)
{
pBuffer += sizeof(m_guidFormatId);
memcpy(pBuffer, m_pCoMemWaveFormatEx, sizeof(WAVEFORMATEX) + m_pCoMemWaveFormatEx->cbSize);
}
return cb;
}
HRESULT Deserialize(const BYTE * pBuffer, ULONG * pcbUsed)
{
HRESULT hr = S_OK;
::CoTaskMemFree(m_pCoMemWaveFormatEx);
m_pCoMemWaveFormatEx = NULL;
*pcbUsed = *((UNALIGNED ULONG *)pBuffer);
pBuffer += sizeof(ULONG);
// Misaligment exception is generated for SHx platform.
// Marking pointer as UNALIGNED does not help.
#ifndef _WIN32_WCE
m_guidFormatId = *((UNALIGNED GUID *)pBuffer);
#else
memcpy(&m_guidFormatId, pBuffer, sizeof(GUID));
#endif
if (*pcbUsed > sizeof(GUID) + sizeof(ULONG))
{
pBuffer += sizeof(m_guidFormatId);
hr = CoMemCopyWFEX((const WAVEFORMATEX *)pBuffer, &m_pCoMemWaveFormatEx);
if (FAILED(hr))
{
m_guidFormatId = GUID_NULL;
}
}
return hr;
}
};
// Return the default codepage given a LCID.
// Note some of the newer locales do not have associated Windows codepages. For these, we return UTF-8.
inline UINT SpCodePageFromLcid(LCID lcid)
{
char achCodePage[6];
return (0 != GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, achCodePage, sizeof(achCodePage))) ? atoi(achCodePage) : 65001;
}
inline HRESULT SPBindToFile( LPCWSTR pFileName, SPFILEMODE eMode, ISpStream ** ppStream,
const GUID * pFormatId = NULL, const WAVEFORMATEX * pWaveFormatEx = NULL,
ULONGLONG ullEventInterest = SPFEI_ALL_EVENTS)
{
HRESULT hr = ::CoCreateInstance(CLSID_SpStream, NULL, CLSCTX_ALL, __uuidof(*ppStream), (void **)ppStream);
if (SUCCEEDED(hr))
{
hr = (*ppStream)->BindToFile(pFileName, eMode, pFormatId, pWaveFormatEx, ullEventInterest);
if (FAILED(hr))
{
(*ppStream)->Release();
*ppStream = NULL;
}
}
return hr;
} /* SPBindToFile */
#ifndef _UNICODE
inline HRESULT SPBindToFile( const TCHAR * pFileName, SPFILEMODE eMode, ISpStream** ppStream,
const GUID * pFormatId = NULL, const WAVEFORMATEX * pWaveFormatEx = NULL,
ULONGLONG ullEventInterest = SPFEI_ALL_EVENTS)
{
WCHAR szWcharFileName[MAX_PATH];
::MultiByteToWideChar(CP_ACP, 0, pFileName, -1, szWcharFileName, sp_countof(szWcharFileName));
return SPBindToFile(szWcharFileName, eMode, ppStream, pFormatId, pWaveFormatEx, ullEventInterest);
}
#endif
/****************************************************************************
* SpClearEvent *
*--------------*
* Description:
* Helper function that can be used by clients that do not use the CSpEvent
* class.
*
* Returns:
*
*****************************************************************************/
inline void SpClearEvent(SPEVENT * pe)
{
if( pe->elParamType != SPEI_UNDEFINED)
{
if( pe->elParamType == SPET_LPARAM_IS_POINTER ||
pe->elParamType == SPET_LPARAM_IS_STRING)
{
::CoTaskMemFree((void *)pe->lParam);
}
else if (pe->elParamType == SPET_LPARAM_IS_TOKEN ||
pe->elParamType == SPET_LPARAM_IS_OBJECT)
{
((IUnknown*)pe->lParam)->Release();
}
}
memset(pe, 0, sizeof(*pe));
}
/****************************************************************************
* SpInitEvent *
*-------------*
* Description:
*
* Returns:
*
*****************************************************************************/
inline void SpInitEvent(SPEVENT * pe)
{
memset(pe, 0, sizeof(*pe));
}
/****************************************************************************
* SpEventSerializeSize *
*----------------------*
* Description:
* Computes the required size of a buffer to serialize an event. The caller
* must specify which type of serialized event is desired -- either SPSERIALIZEDEVENT
* or SPSERIALIZEDEVENT64.
*
* Returns:
* Size in bytes required to seriailze the event.
*
****************************************************************************/
// WCE compiler does not work propertly with template
#ifndef _WIN32_WCE
template <class T>
inline ULONG SpEventSerializeSize(const SPEVENT * pEvent)
{
ULONG ulSize = sizeof(T);
#else
inline ULONG SpEventSerializeSize(const SPEVENT * pEvent, ULONG ulSize)
{
#endif //_WIN32_WCE
if( ( pEvent->elParamType == SPET_LPARAM_IS_POINTER ) && pEvent->lParam )
{
ulSize += ULONG(pEvent->wParam);
}
else if ((pEvent->elParamType == SPET_LPARAM_IS_STRING) && pEvent->lParam != NULL)
{
ulSize += (wcslen((WCHAR*)pEvent->lParam) + 1) * sizeof( WCHAR );
}
else if( pEvent->elParamType == SPET_LPARAM_IS_TOKEN )
{
CSpDynamicString dstrObjectId;
if( ((ISpObjectToken*)(pEvent->lParam))->GetId( &dstrObjectId ) == S_OK )
{
ulSize += (dstrObjectId.Length() + 1) * sizeof( WCHAR );
}
}
// Round up to nearest DWORD
ulSize += 3;
ulSize -= ulSize % 4;
return ulSize;
}
/****************************************************************************
* SpSerializedEventSize *
*-----------------------*
* Description:
* Returns the size, in bytes, used by a serialized event. The caller can
* pass a pointer to either a SPSERIAILZEDEVENT or SPSERIALIZEDEVENT64 structure.
*
* Returns:
* Number of bytes used by serizlied event
*
********************************************************************* RAL ***/
// WCE compiler does not work propertly with template
#ifndef _WIN32_WCE
template <class T>
inline ULONG SpSerializedEventSize(const T * pSerEvent)
{
ULONG ulSize = sizeof(T);
if( ( pSerEvent->elParamType == SPET_LPARAM_IS_POINTER ) && pSerEvent->SerializedlParam )
{
ulSize += ULONG(pSerEvent->SerializedwParam);
}
else if ((pSerEvent->elParamType == SPET_LPARAM_IS_STRING || pSerEvent->elParamType == SPET_LPARAM_IS_TOKEN) &&
pSerEvent->SerializedlParam != NULL)
{
ulSize += (wcslen((WCHAR*)(pSerEvent + 1)) + 1) * sizeof( WCHAR );
}
// Round up to nearest DWORD
ulSize += 3;
ulSize -= ulSize % 4;
return ulSize;
}
#else //_WIN32_WCE
inline ULONG SpSerializedEventSize(const SPSERIALIZEDEVENT * pSerEvent, ULONG ulSize)
{
if( ( pSerEvent->elParamType == SPET_LPARAM_IS_POINTER ) && pSerEvent->SerializedlParam )
{
ulSize += ULONG(pSerEvent->SerializedwParam);
}
else if ((pSerEvent->elParamType == SPET_LPARAM_IS_STRING || pSerEvent->elParamType == SPET_LPARAM_IS_TOKEN) &&
pSerEvent->SerializedlParam != NULL)
{
ulSize += (wcslen((WCHAR*)(pSerEvent + 1)) + 1) * sizeof( WCHAR );
}
// Round up to nearest DWORD
ulSize += 3;
ulSize -= ulSize % 4;
return ulSize;
}
inline ULONG SpSerializedEventSize(const SPSERIALIZEDEVENT64 * pSerEvent, ULONG ulSize)
{
if( ( pSerEvent->elParamType == SPET_LPARAM_IS_POINTER ) && pSerEvent->SerializedlParam )
{
ulSize += ULONG(pSerEvent->SerializedwParam);
}
else if ((pSerEvent->elParamType == SPET_LPARAM_IS_STRING || pSerEvent->elParamType == SPET_LPARAM_IS_TOKEN) &&
pSerEvent->SerializedlParam != NULL)
{
ulSize += (wcslen((WCHAR*)(pSerEvent + 1)) + 1) * sizeof( WCHAR );
}
// Round up to nearest DWORD
ulSize += 3;
ulSize -= ulSize % 4;
return ulSize;
}
#endif //_WIN32_WCE
/*** CSpEvent helper class
*
*/
class CSpEvent : public SPEVENT
{
public:
CSpEvent()
{
SpInitEvent(this);
}
~CSpEvent()
{
SpClearEvent(this);
}
// If you need to take the address of a CSpEvent that is not const, use the AddrOf() method
// which will do debug checking of parameters. If you encounter this problem when calling
// GetEvents from an event source, you may want to use the GetFrom() method of this class.
const SPEVENT * operator&()
{
return this;
}
CSpEvent * AddrOf()
{
// Note: This method does not ASSERT since we assume the caller knows what they are doing.
return this;
}
void Clear()
{
SpClearEvent(this);
}
HRESULT CopyTo(SPEVENT * pDestEvent) const
{
memcpy(pDestEvent, this, sizeof(*pDestEvent));
if ((elParamType == SPET_LPARAM_IS_POINTER) && lParam)
{
SPDBG_ASSERT(wParam && (wParam < 0x100000)); // this is too big!
pDestEvent->lParam = (LPARAM)::CoTaskMemAlloc(wParam);
if (pDestEvent->lParam)
{
memcpy((void *)pDestEvent->lParam, (void *)lParam, wParam);
}
else
{
pDestEvent->eEventId = SPEI_UNDEFINED;
return E_OUTOFMEMORY;
}
}
else if (elParamType == SPET_LPARAM_IS_STRING && lParam != NULL)
{
pDestEvent->lParam = (LPARAM)::CoTaskMemAlloc((wcslen((WCHAR*)lParam) + 1) * sizeof(WCHAR));
if (pDestEvent->lParam)
{
wcscpy((WCHAR*)pDestEvent->lParam, (WCHAR*)lParam);
}
else
{
pDestEvent->eEventId = SPEI_UNDEFINED;
return E_OUTOFMEMORY;
}
}
else if (elParamType == SPET_LPARAM_IS_TOKEN ||
elParamType == SPET_LPARAM_IS_OBJECT)
{
((IUnknown*)lParam)->AddRef();
}
return S_OK;
}
HRESULT GetFrom(ISpEventSource * pEventSrc)
{
SpClearEvent(this);
return pEventSrc->GetEvents(1, this, NULL);
}
HRESULT CopyFrom(const SPEVENT * pSrcEvent)
{
SpClearEvent(this);
return static_cast<const CSpEvent *>(pSrcEvent)->CopyTo(this);
}
void Detach(SPEVENT * pDestEvent = NULL)
{
if (pDestEvent)
{
memcpy(pDestEvent, this, sizeof(*pDestEvent));
}
memset(this, 0, sizeof(*this));
}
template <class T>
ULONG SerializeSize() const
{
return SpEventSerializeSize<T>(this);
}
// Call this method with either SPSERIALIZEDEVENT or SPSERIALIZEDEVENT64
template <class T>
void Serialize(T * pSerEvent) const
{
SPDBG_ASSERT(elParamType != SPET_LPARAM_IS_OBJECT);
pSerEvent->eEventId = this->eEventId;
pSerEvent->elParamType = this->elParamType;
pSerEvent->ulStreamNum = this->ulStreamNum;
pSerEvent->ullAudioStreamOffset = this->ullAudioStreamOffset;
pSerEvent->SerializedwParam = static_cast<ULONG>(this->wParam);
pSerEvent->SerializedlParam = static_cast<LONG>(this->lParam);
if (lParam)
{
switch(elParamType)
{
case SPET_LPARAM_IS_POINTER:
memcpy(pSerEvent + 1, (void *)lParam, wParam);
pSerEvent->SerializedlParam = sizeof(T);
break;
case SPET_LPARAM_IS_STRING:
wcscpy((WCHAR *)(pSerEvent + 1), (WCHAR*)lParam);
pSerEvent->SerializedlParam = sizeof(T);
break;
case SPET_LPARAM_IS_TOKEN:
{
CSpDynamicString dstrObjectId;
if( SUCCEEDED( ((ISpObjectToken*)lParam)->GetId( &dstrObjectId ) ) )
{
pSerEvent->SerializedwParam = (dstrObjectId.Length() + 1) * sizeof( WCHAR );;
memcpy( pSerEvent + 1, (void *)dstrObjectId.m_psz, static_cast<ULONG>(pSerEvent->SerializedwParam) );
}
pSerEvent->SerializedlParam = sizeof(T);
}
break;
default:
break;
}
}
}
template <class T>
HRESULT Serialize(T ** ppCoMemSerEvent, ULONG * pcbSerEvent) const
{
// WCE compiler does not work propertly with template
#ifndef _WIN32_WCE
*pcbSerEvent = SpEventSerializeSize<T>(this);
#else
*pcbSerEvent = SpEventSerializeSize(this, sizeof(** ppCoMemSerEvent));
#endif
*ppCoMemSerEvent = (T *)::CoTaskMemAlloc(*pcbSerEvent);
if (*ppCoMemSerEvent)
{
Serialize(*ppCoMemSerEvent);
return S_OK;
}
else
{
*pcbSerEvent = 0;
return E_OUTOFMEMORY;
}
}
// Call this method with either SPSERIALIZEDEVENT or SPSERIALIZEDEVENT64
template <class T>
HRESULT Deserialize(const T * pSerEvent, ULONG * pcbUsed = NULL)
{
Clear();
HRESULT hr = S_OK;
const UNALIGNED T * pTemp = pSerEvent;
this->eEventId = pTemp->eEventId;
this->elParamType = pTemp->elParamType;
this->ulStreamNum = pTemp->ulStreamNum;
this->ullAudioStreamOffset = pTemp->ullAudioStreamOffset;
this->wP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -