⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sphelper.h

📁 TTS语音开发示例
💻 H
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************
* SPHelper.h *
*------------*
*   Description:
*       This is the header file for core helper functions implementation.
*-------------------------------------------------------------------------------
*   Copyright (c) Microsoft Corporation. All rights reserved.
*******************************************************************************/
#ifndef SPHelper_h
#define SPHelper_h

#ifndef _INC_MALLOC
#include <malloc.h>
#endif

#ifndef _INC_CRTDBG
#include <crtdbg.h>
#endif

#ifndef __sapi_h__
#include <sapi.h>
#endif

#ifndef __sapiddk_h__
#include <sapiddk.h>
#endif

#ifndef SPError_h
#include <SPError.h>
#endif

#ifndef SPDebug_h
#include <SPDebug.h>
#endif

#ifndef _INC_LIMITS
#include <limits.h>
#endif

#ifndef _INC_MMSYSTEM
#include <mmsystem.h>
#endif

#ifndef __comcat_h__
#include <comcat.h>
#endif

#ifndef _INC_MMREG
#include <mmreg.h>
#endif

#ifndef __ATLBASE_H__
#include <atlbase.h>
#endif

//=== Constants ==============================================================
#define sp_countof(x) ((sizeof(x) / sizeof(*(x))))

/*** CSpDynamicString helper class
*
*/
class CSpDynamicString 
{
public:

    WCHAR *     m_psz;
    CSpDynamicString()
    {
        m_psz = NULL;
    }
    CSpDynamicString(ULONG cchReserve)
    {
        m_psz = (WCHAR *)::CoTaskMemAlloc(cchReserve * sizeof(WCHAR));
    }
    WCHAR * operator=(const CSpDynamicString& src)
    {
        if (m_psz != src.m_psz)
        {
            ::CoTaskMemFree(m_psz);
            m_psz = src.Copy();
        }
        return m_psz;
    }
    WCHAR * operator=(const WCHAR * pSrc)
    {
        Clear();
        if (pSrc)
        {
            ULONG cbNeeded = (wcslen(pSrc) + 1) * sizeof(WCHAR);
            m_psz = (WCHAR *)::CoTaskMemAlloc(cbNeeded);
            SPDBG_ASSERT(m_psz);
            if (m_psz)
            {
                memcpy(m_psz, pSrc, cbNeeded);    
            }
        }
        return m_psz;
    }

    WCHAR * operator=(const char * pSrc)
    {
        Clear();
        if (pSrc)
        {
            ULONG cbNeeded = (lstrlenA(pSrc) + 1) * sizeof(WCHAR);
            m_psz = (WCHAR *)::CoTaskMemAlloc(cbNeeded);
            SPDBG_ASSERT(m_psz);
            if (m_psz)
            {
                ::MultiByteToWideChar(CP_ACP, 0, pSrc, -1, m_psz, cbNeeded/sizeof(WCHAR));
            }
        }
        return m_psz;
    }

    WCHAR * operator=(REFGUID rguid)
    {
        Clear();
        ::StringFromCLSID(rguid, &m_psz);
        return m_psz;
    }


    /*explicit*/ CSpDynamicString(const WCHAR * pSrc)
    {
        m_psz = NULL;
        operator=(pSrc);
    }
    /*explicit*/ CSpDynamicString(const char * pSrc)
    {
        m_psz = NULL;
        operator=(pSrc);
    }
    /*explicit*/ CSpDynamicString(const CSpDynamicString& src)
    {
        m_psz = src.Copy();
    }
    /*explicit*/ CSpDynamicString(REFGUID rguid)
    {
        ::StringFromCLSID(rguid, &m_psz);
    }


    ~CSpDynamicString()
    {
        ::CoTaskMemFree(m_psz);
    }
    unsigned int Length() const
    {
        return (m_psz == NULL)? 0 : wcslen(m_psz);
    }

    operator WCHAR * () const
    {
        return m_psz;
    }
    //The assert on operator& usually indicates a bug.  If this is really
    //what is needed, however, take the address of the m_psz member explicitly.
    WCHAR ** operator&()
    {
        SPDBG_ASSERT(m_psz == NULL);
        return &m_psz;
    }

    WCHAR * Append(const WCHAR * pszSrc)
    {
        if (pszSrc)
        {
            ULONG lenSrc = wcslen(pszSrc);
            if (lenSrc)
            {
                ULONG lenMe = Length();
                WCHAR *pszNew = (WCHAR *)::CoTaskMemAlloc((lenMe + lenSrc + 1) * sizeof(WCHAR));
                if (pszNew)
                {
                    if (m_psz)  // Could append to an empty string so check...
                    {
                        if (lenMe)
                        {
                            memcpy(pszNew, m_psz, lenMe * sizeof(WCHAR));
                        }
                        ::CoTaskMemFree(m_psz);
                    }
                    memcpy(pszNew + lenMe, pszSrc, (lenSrc + 1) * sizeof(WCHAR));
                    m_psz = pszNew;
                }
                else
                {
                    SPDBG_ASSERT(FALSE);
                }
            }
        }
        return m_psz;
    }

    WCHAR * Append(const WCHAR * pszSrc, const ULONG lenSrc)
    {
        if (pszSrc && lenSrc)
        {
            ULONG lenMe = Length();
            WCHAR *pszNew = (WCHAR *)::CoTaskMemAlloc((lenMe + lenSrc + 1) * sizeof(WCHAR));
            if (pszNew)
            {
                if (m_psz)  // Could append to an empty string so check...
                {
                    if (lenMe)
                    {
                        memcpy(pszNew, m_psz, lenMe * sizeof(WCHAR));
                    }
                    ::CoTaskMemFree(m_psz);
                }
                memcpy(pszNew + lenMe, pszSrc, lenSrc * sizeof(WCHAR));
                *(pszNew + lenMe + lenSrc) = L'\0';
                m_psz = pszNew;
            }
            else
            {
                SPDBG_ASSERT(FALSE);
            }
        }
        return m_psz;
    }

    WCHAR * Append2(const WCHAR * pszSrc1, const WCHAR * pszSrc2)
    {
        ULONG lenSrc1 = pszSrc1 ? wcslen(pszSrc1) : 0;
        ULONG lenSrc2 = pszSrc2 ? wcslen(pszSrc2) : 0;

        if (lenSrc1 || lenSrc2)
        {
            ULONG lenMe = Length();
            WCHAR *pszNew = (WCHAR *)::CoTaskMemAlloc((lenMe + lenSrc1 + lenSrc2 + 1) * sizeof(WCHAR));
            if (pszNew)
            {
                if (m_psz)  // Could append to an empty string so check...
                {
                    if (lenMe)
                    {
                        memcpy(pszNew, m_psz, lenMe * sizeof(WCHAR));
                    }
                    ::CoTaskMemFree(m_psz);
                }
                // In both of these cases, we copy the trailing NULL so that we're sure it gets
                // there (if lenSrc2 is 0 then we better copy it from pszSrc1).
                if (lenSrc1)
                {
                    memcpy(pszNew + lenMe, pszSrc1, (lenSrc1 + 1) * sizeof(WCHAR));
                }
                if (lenSrc2)
                {
                    memcpy(pszNew + lenMe + lenSrc1, pszSrc2, (lenSrc2 + 1) * sizeof(WCHAR));
                }
                m_psz = pszNew;
            }
            else
            {
                SPDBG_ASSERT(FALSE);
            }
        }
        return m_psz;
    }
    WCHAR * Copy() const
    {
        if (m_psz)
        {
            CSpDynamicString szNew(m_psz);
            return szNew.Detach();
        }
        return NULL;
    }
    CHAR * CopyToChar() const
    {
        if (m_psz)
        {
            CHAR* psz;
            ULONG cbNeeded = ::WideCharToMultiByte(CP_ACP, 0, m_psz, -1, NULL, NULL, NULL, NULL);
            psz = (CHAR *)::CoTaskMemAlloc(cbNeeded);
            SPDBG_ASSERT(psz);
            if (psz)
            {
                ::WideCharToMultiByte(CP_ACP, 0, m_psz, -1, psz, cbNeeded/sizeof(CHAR), NULL, NULL);
            }
            return psz;
        }
        return NULL;
    }
    void Attach(WCHAR * pszSrc)
    {
        SPDBG_ASSERT(m_psz == NULL);
        m_psz = pszSrc;
    }
    WCHAR * Detach()
    {
        WCHAR * s = m_psz;
        m_psz = NULL;
        return s;
    }
    void Clear()
    {
        ::CoTaskMemFree(m_psz);
        m_psz = NULL;
    }
    bool operator!() const
    {
        return (m_psz == NULL);
    }
    HRESULT CopyToBSTR(BSTR * pbstr)
    {
        if (m_psz)
        {
            *pbstr = ::SysAllocString(m_psz);
            if (*pbstr == NULL)
            {
                return E_OUTOFMEMORY;
            }
        }
        else
        {
            *pbstr = NULL;
        }
        return S_OK;
    }
    void TrimToSize(ULONG ulNumChars)
    {
        if (m_psz && ulNumChars < Length())
        {
            m_psz[ulNumChars] = 0;
        }
    }
    WCHAR * Compact()
    {
        if (m_psz)
        {
            ULONG cch = wcslen(m_psz);
            m_psz = (WCHAR *)::CoTaskMemRealloc(m_psz, (cch + 1) * sizeof(WCHAR));
        }
        return m_psz;
    }
    WCHAR * ClearAndGrowTo(ULONG cch)
    {
        if (m_psz)
        {
            Clear();
        }
        m_psz = (WCHAR *)::CoTaskMemAlloc(cch * sizeof(WCHAR));
        return m_psz;
    }
    WCHAR * LTrim()
    {
        if (m_psz)
        {
            WCHAR * pszRead = m_psz;
            while (iswspace(*pszRead))
            {
                pszRead++;
            }
            if (pszRead != m_psz)
            {
                WCHAR * pszWrite = m_psz;
                while (*pszRead)
                {
                    *pszWrite++ = *pszRead++;
                }
                *pszWrite = '\0';
            }
        }
        return m_psz;
    }
    WCHAR * RTrim()
    {
        if (m_psz)
        {
            WCHAR * pszTail = m_psz + wcslen(m_psz);
            WCHAR * pszZeroTerm = pszTail;
            while (pszZeroTerm > m_psz && iswspace(pszZeroTerm[-1]))
            {
                pszZeroTerm--;
            }
            if (pszZeroTerm != pszTail)
            {
                *pszZeroTerm = '\0';
            }
        }
        return m_psz;        
    }
    WCHAR * TrimBoth()
    {
        RTrim();
        return LTrim();
    }
};



//
//  Simple inline function converts a ulong to a hex string.
//
inline void SpHexFromUlong(WCHAR * psz, ULONG ul)
{
    const static WCHAR szHexChars[] = L"0123456789ABCDEF";
    if (ul == 0)
    {
        psz[0] = L'0';
        psz[1] = 0;
    }
    else
    {
        ULONG ulChars = 1;
        psz[0] = 0;
        while (ul)
        {
            memmove(psz + 1, psz, ulChars * sizeof(WCHAR));
            psz[0] = szHexChars[ul % 16];
            ul /= 16;
            ulChars++;
        }
    }
}


//=== Token helpers

inline HRESULT SpGetTokenFromId(
    const WCHAR * pszTokenId, 
    ISpObjectToken ** ppToken,
    BOOL fCreateIfNotExist = FALSE)
{
    SPDBG_FUNC("SpGetTokenFromId");
    HRESULT hr;
    
    CComPtr<ISpObjectToken> cpToken;
    hr = cpToken.CoCreateInstance(CLSID_SpObjectToken);
    
    if (SUCCEEDED(hr))
    {
        hr = cpToken->SetId(NULL, pszTokenId, fCreateIfNotExist);
    }
    
    if (SUCCEEDED(hr))
    {
        *ppToken = cpToken.Detach();
    }
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -