📄 sphelper.h
字号:
SPDBG_REPORT_ON_FAIL(hr);
}
return hr;
}
inline HRESULT SpCreatePhoneConverter(
LANGID LangID,
const WCHAR * pszReqAttribs,
const WCHAR * pszOptAttribs,
ISpPhoneConverter ** ppPhoneConverter)
{
SPDBG_FUNC("SpCreatePhoneConverter");
HRESULT hr;
if (LangID == 0)
{
hr = E_INVALIDARG;
}
else
{
CSpDynamicString dstrReqAttribs;
if (pszReqAttribs)
{
dstrReqAttribs = pszReqAttribs;
dstrReqAttribs.Append(L";");
}
WCHAR szLang[MAX_PATH];
SpHexFromUlong(szLang, LangID);
WCHAR szLangCondition[MAX_PATH];
wcscpy(szLangCondition, L"Language=");
wcscat(szLangCondition, szLang);
dstrReqAttribs.Append(szLangCondition);
hr = SpCreateBestObject(SPCAT_PHONECONVERTERS, dstrReqAttribs, pszOptAttribs, ppPhoneConverter);
}
if (hr != SPERR_NOT_FOUND)
{
SPDBG_REPORT_ON_FAIL(hr);
}
return hr;
}
/****************************************************************************
* SpHrFromWin32 *
*---------------*
* Description:
* This inline function works around a basic problem with the macro
* HRESULT_FROM_WIN32. The macro forces the expresion in ( ) to be evaluated
* two times. By using this inline function, the expression will only be
* evaluated once.
*
* Returns:
* HRESULT of converted Win32 error code
*
*****************************************************************************/
inline HRESULT SpHrFromWin32(DWORD dwErr)
{
return HRESULT_FROM_WIN32(dwErr);
}
/****************************************************************************
* SpHrFromLastWin32Error *
*------------------------*
* Description:
* This simple inline function is used to return a converted HRESULT
* from the Win32 function ::GetLastError. Note that using HRESULT_FROM_WIN32
* will evaluate the error code twice so we don't want to use:
*
* HRESULT_FROM_WIN32(::GetLastError())
*
* since that will call GetLastError twice.
* On Win98 and WinMe ::GetLastError() returns 0 for some functions (see MSDN).
* We therefore check for that and return E_FAIL. This function should only be
* called in an error case since it will always return an error code!
*
* Returns:
* HRESULT for ::GetLastError()
*
*****************************************************************************/
inline HRESULT SpHrFromLastWin32Error()
{
DWORD dw = ::GetLastError();
return (dw == 0) ? E_FAIL : SpHrFromWin32(dw);
}
/****************************************************************************
* SpGetUserDefaultUILanguage *
*----------------------------*
* Description:
* Returns the default user interface language, using a method
* appropriate to the platform (Windows 9x, Windows NT, or Windows 2000)
*
* Returns:
* Default UI language
*
*****************************************************************************/
inline LANGID SpGetUserDefaultUILanguage(void)
{
HRESULT hr = S_OK;
LANGID wUILang = 0;
OSVERSIONINFO Osv ;
Osv.dwOSVersionInfoSize = sizeof(Osv) ;
if(!GetVersionEx(&Osv))
{
hr = SpHrFromLastWin32Error();
}
// Get the UI language by one of three methods, depending on the system
else if(Osv.dwPlatformId != VER_PLATFORM_WIN32_NT)
{
// Case 1: Running on Windows 9x. Get the system UI language from registry:
CHAR szData[32];
DWORD dwSize = sizeof(szData) ;
HKEY hKey;
long lRet = RegOpenKeyEx(
HKEY_USERS,
_T(".Default\\Control Panel\\desktop\\ResourceLocale"),
0,
KEY_READ,
&hKey);
#ifdef _WIN32_WCE_BUG_10655
if (lRet == ERROR_INVALID_PARAMETER)
{
lRet = ERROR_FILE_NOT_FOUND;
}
#endif // _WIN32_WCE_BUG_10655
hr = SpHrFromWin32(lRet);
if (SUCCEEDED(hr))
{
lRet = RegQueryValueEx(
hKey,
_T(""),
NULL,
NULL,
(BYTE *)szData,
&dwSize);
#ifdef _WIN32_WCE_BUG_10655
if(lRet == ERROR_INVALID_PARAMETER)
{
lRet = ERROR_FILE_NOT_FOUND;
}
#endif //_WIN32_WCE_BUG_10655
hr = SpHrFromWin32(lRet);
::RegCloseKey(hKey) ;
}
if (SUCCEEDED(hr))
{
// Convert string to number
wUILang = (LANGID) strtol(szData, NULL, 16) ;
}
}
else if (Osv.dwMajorVersion >= 5.0)
{
// Case 2: Running on Windows 2000 or later. Use GetUserDefaultUILanguage to find
// the user's prefered UI language
HMODULE hMKernel32 = ::LoadLibraryW(L"kernel32.dll") ;
if (hMKernel32 == NULL)
{
hr = SpHrFromLastWin32Error();
}
else
{
LANGID (WINAPI *pfnGetUserDefaultUILanguage) () =
(LANGID (WINAPI *)(void))
#ifdef _WIN32_WCE
GetProcAddress(hMKernel32, L"GetUserDefaultUILanguage") ;
#else
GetProcAddress(hMKernel32, "GetUserDefaultUILanguage") ;
#endif
if(NULL != pfnGetUserDefaultUILanguage)
{
wUILang = pfnGetUserDefaultUILanguage() ;
}
else
{ // GetProcAddress failed
hr = SpHrFromLastWin32Error();
}
::FreeLibrary(hMKernel32);
}
}
else {
// Case 3: Running on Windows NT 4.0 or earlier. Get UI language
// from locale of .default user in registry:
// HKEY_USERS\.DEFAULT\Control Panel\International\Locale
WCHAR szData[32] ;
DWORD dwSize = sizeof(szData) ;
HKEY hKey ;
LONG lRet = RegOpenKeyEx(HKEY_USERS,
_T(".DEFAULT\\Control Panel\\International"),
0,
KEY_READ,
&hKey);
#ifdef _WIN32_WCE_BUG_10655
if(lRet == ERROR_INVALID_PARAMETER)
{
lRet = ERROR_FILE_NOT_FOUND;
}
#endif //_WIN32_WCE_BUG_10655
hr = SpHrFromWin32(lRet);
if (SUCCEEDED(hr))
{
lRet = RegQueryValueEx(
hKey,
_T("Locale"),
NULL,
NULL,
(BYTE *)szData,
&dwSize);
#ifdef _WIN32_WCE_BUG_10655
if(lRet == ERROR_INVALID_PARAMETER)
{
lRet = ERROR_FILE_NOT_FOUND;
}
#endif //_WIN32_WCE_BUG_10655
hr = SpHrFromWin32(lRet);
::RegCloseKey(hKey);
}
if (SUCCEEDED(hr))
{
// Convert string to number
wUILang = (LANGID) wcstol(szData, NULL, 16) ;
if(0x0401 == wUILang || // Arabic
0x040d == wUILang || // Hebrew
0x041e == wUILang // Thai
)
{
// Special case these to the English UI.
// These versions of Windows NT 4.0 were enabled only, i.e., the
// UI was English. However, the registry setting
// HKEY_USERS\.DEFAULT\Control Panel\International\Locale was set
// to the respective locale for application compatibility.
wUILang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US) ;
}
}
}
return (wUILang ? wUILang : ::GetUserDefaultLangID()); // In failure case, try our best!
}
inline HRESULT SpGetDescription(ISpObjectToken * pObjToken, WCHAR ** ppszDescription, LANGID Language = SpGetUserDefaultUILanguage())
{
WCHAR szLangId[10];
SpHexFromUlong(szLangId, Language);
HRESULT hr = pObjToken->GetStringValue(szLangId, ppszDescription);
if (hr == SPERR_NOT_FOUND)
{
hr = pObjToken->GetStringValue(NULL, ppszDescription);
}
return hr;
}
inline HRESULT SpSetDescription(ISpObjectToken * pObjToken, const WCHAR * pszDescription, LANGID Language = SpGetUserDefaultUILanguage(), BOOL fSetLangIndependentId = TRUE)
{
WCHAR szLangId[10];
SpHexFromUlong(szLangId, Language);
HRESULT hr = pObjToken->SetStringValue(szLangId, pszDescription);
if (SUCCEEDED(hr) && fSetLangIndependentId)
{
hr = pObjToken->SetStringValue(NULL, pszDescription);
}
return hr;
}
/****************************************************************************
* SpConvertStreamFormatEnum *
*---------------------------*
* Description:
* This method converts the specified stream format into a wave format
* structure.
*
*****************************************************************************/
inline HRESULT SpConvertStreamFormatEnum(SPSTREAMFORMAT eFormat, GUID * pFormatId, WAVEFORMATEX ** ppCoMemWaveFormatEx)
{
HRESULT hr = S_OK;
if(pFormatId==NULL || ::IsBadWritePtr(pFormatId, sizeof(*pFormatId))
|| ppCoMemWaveFormatEx==NULL || ::IsBadWritePtr(ppCoMemWaveFormatEx, sizeof(*ppCoMemWaveFormatEx)))
{
return E_INVALIDARG;
}
const GUID * pFmtGuid = &GUID_NULL; // Assume failure case
if( eFormat >= SPSF_8kHz8BitMono && eFormat <= SPSF_48kHz16BitStereo )
{
WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc(sizeof(WAVEFORMATEX));
*ppCoMemWaveFormatEx = pwfex;
if (pwfex)
{
DWORD dwIndex = eFormat - SPSF_8kHz8BitMono;
BOOL bIsStereo = dwIndex & 0x1;
BOOL bIs16 = dwIndex & 0x2;
DWORD dwKHZ = (dwIndex & 0x3c) >> 2;
static const DWORD adwKHZ[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 };
pwfex->wFormatTag = WAVE_FORMAT_PCM;
pwfex->nChannels = pwfex->nBlockAlign = (WORD)(bIsStereo ? 2 : 1);
pwfex->nSamplesPerSec = adwKHZ[dwKHZ];
pwfex->wBitsPerSample = 8;
if (bIs16)
{
pwfex->wBitsPerSample *= 2;
pwfex->nBlockAlign *= 2;
}
pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nBlockAlign;
pwfex->cbSize = 0;
pFmtGuid = &SPDFID_WaveFormatEx;
}
else
{
hr = E_OUTOFMEMORY;
}
}
else if( eFormat == SPSF_TrueSpeech_8kHz1BitMono )
{
int NumBytes = sizeof( WAVEFORMATEX ) + 32;
WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc( NumBytes );
*ppCoMemWaveFormatEx = pwfex;
if( pwfex )
{
memset( pwfex, 0, NumBytes );
pwfex->wFormatTag = WAVE_FORMAT_DSPGROUP_TRUESPEECH;
pwfex->nChannels = 1;
pwfex->nSamplesPerSec = 8000;
pwfex->nAvgBytesPerSec = 1067;
pwfex->nBlockAlign = 32;
pwfex->wBitsPerSample = 1;
pwfex->cbSize = 32;
BYTE* pExtra = ((BYTE*)pwfex) + sizeof( WAVEFORMATEX );
pExtra[0] = 1;
pExtra[2] = 0xF0;
pFmtGuid = &SPDFID_WaveFormatEx;
}
else
{
hr = E_OUTOFMEMORY;
}
}
else if( (eFormat >= SPSF_CCITT_ALaw_8kHzMono ) &&
(eFormat <= SPSF_CCITT_ALaw_44kHzStereo ) )
{
WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc( sizeof(WAVEFORMATEX) );
*ppCoMemWaveFormatEx = pwfex;
if( pwfex )
{
memset( pwfex, 0, sizeof(WAVEFORMATEX) );
DWORD dwIndex = eFormat - SPSF_CCITT_ALaw_8kHzMono;
DWORD dwKHZ = dwIndex / 2;
static const DWORD adwKHZ[] = { 8000, 11025, 22050, 44100 };
BOOL bIsStereo = dwIndex & 0x1;
pwfex->wFormatTag = WAVE_FORMAT_ALAW;
pwfex->nChannels = pwfex->nBlockAlign = (WORD)(bIsStereo ? 2 : 1);
pwfex->nSamplesPerSec = adwKHZ[dwKHZ];
pwfex->wBitsPerSample = 8;
pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nBlockAlign;
pwfex->cbSize = 0;
pFmtGuid = &SPDFID_WaveFormatEx;
}
else
{
hr = E_OUTOFMEMORY;
}
}
else if( (eFormat >= SPSF_CCITT_uLaw_8kHzMono ) &&
(eFormat <= SPSF_CCITT_uLaw_44kHzStereo ) )
{
WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc( sizeof(WAVEFORMATEX) );
*ppCoMemWaveFormatEx = pwfex;
if( pwfex )
{
memset( pwfex, 0, sizeof(WAVEFORMATEX) );
DWORD dwIndex = eFormat - SPSF_CCITT_uLaw_8kHzMono;
DWORD dwKHZ = dwIndex / 2;
static const DWORD adwKHZ[] = { 8000, 11025, 22050, 44100 };
BOOL bIsStereo = dwIndex & 0x1;
pwfex->wFormatTag = WAVE_FORMAT_MULAW;
pwfex->nChannels = pwfex->nBlockAlign = (WORD)(bIsStereo ? 2 : 1);
pwfex->nSamplesPerSec = adwKHZ[dwKHZ];
pwfex->wBitsPerSample = 8;
pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nBlockAlign;
pwfex->cbSize = 0;
pFmtGuid = &SPDFID_WaveFormatEx;
}
else
{
hr = E_OUTOFMEMORY;
}
}
else if( (eFormat >= SPSF_ADPCM_8kHzMono ) &&
(eFormat <= SPSF_ADPCM_44kHzStereo ) )
{
int NumBytes = sizeof( WAVEFORMATEX ) + 32;
WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc( NumBytes );
*ppCoMemWaveFormatEx = pwfex;
if( pwfex )
{
//--- Some of these values seem odd. We used what the codec told us.
static const DWORD adwKHZ[] = { 8000, 11025, 22050, 44100 };
static const DWORD BytesPerSec[] = { 4096, 8192, 5644, 11289, 11155, 22311, 22179, 44359 };
static const DWORD BlockAlign[] = { 256, 256, 512, 1024 };
static const BYTE Extra811[32] =
{
0xF4, 0x01, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x02, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xC0, 0x00, 0x40, 0x00, 0xF0, 0x00, 0x00, 0x00,
0xCC, 0x01, 0x30, 0xFF, 0x88, 0x01, 0x18, 0xFF
};
static const BYTE Extra22[32] =
{
0xF4, 0x03, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x02, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xC0, 0x00, 0x40, 0x00, 0xF0, 0x00, 0x00, 0x00,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -