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

📄 sdkemsviewerruleclient.cpp

📁 WIndows mobile 5.0 pocket pc sdk sample for win32
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    CBRH((pPicture->ValidateData()), hr);

                    //Convert data to string for message body
                    CBRH((pPicture->ToString(&pszTemp)), hr);
                    
                    //Done with our picture object
                    SAFE_DELETE(pPicture);

                    //inc the base offset
                    if(emshi.pszUserData)
                    {
                        //Text + the picture
                        uBaseOffset += (_tcslen(emshi.pszUserData));
                    }
                    else
                    {
                        uBaseOffset++; //just the picture
                    }
                    uCount += chIEIDL;  //point to next IEI
                    uObjCount++;        //Increase object count
                    break;
                }

                /*
               NYI...to implement, simply fill in each of the defined 
               classes and place code here to handle their instantiation 
               and use.  Or define your own objects, etc.
               */
                case IEI_TEXT_FORMATTING:
                case IEI_PREDEFINED_SOUND:
                case IEI_USERDEFINED_SOUND:
                case IEI_PREDEFINED_ANIM:
                case IEI_LARGE_ANIM:
                case IEI_SMALL_ANIM:
                case IEI_USER_PROMPT:
                {
                    //For now, skip the object, don't update uBaseOffset or 
                    //uObjCount, it's like it doesn't exist
                    uCount += chIEIDL;

                    if(emshi.pszUserData)   //Still want the text portion
                    {
                        //[ID = IEI_TEXT_ONLY][Text Len][Text]
                        UINT    uConv       = 0;
                        UINT    uPos        = 0;
                        UINT    uStrLen     = 0;
                        TCHAR   szConv[3]   = _T("");

                        ASSERT(emshi.pszUserData);
                        uStrLen = _tcslen(emshi.pszUserData);

                        pszTemp = (TCHAR*)malloc(sizeof(TCHAR) * (uStrLen + 5));
                        ASSERT(pszTemp);

                        ZeroMemory(pszTemp, sizeof(TCHAR) * (_tcslen(emshi.pszUserData) + 5));
                        _tcscat(pszTemp, _T("FF")); //IEI_TEXT_ONLY

                        szConv[0] = _T('0');
                        uPos = (uStrLen < 0x10) ? 1 : 0;
                        _itot(uStrLen, &(szConv[uPos]), BASE_HEX);
                        _tcscat(pszTemp, szConv);

                        _tcscat(pszTemp, emshi.pszUserData);
                        uObjCount++;        //Increase object count
                        uBaseOffset += uStrLen;
                    }
                    break;
                }

                default:
                {
                    //shouldn't get any IEIs here that aren't handled
                    //or at least recognized
                    ASSERT(FALSE);
                    hr = E_FAIL;
                    goto Exit;
                }
            }
        }
    }
        
    if(NULL == szBodyOut)  //First time saving to buffer
    {
        //+1 for NULL +4 for Object Length
        UINT uLen = _tcslen(pszTemp) + 5;
        szBodyOut = (TCHAR*)malloc(sizeof(TCHAR) * (uLen));
        CBRH((NULL != szBodyOut), hr);
        ZeroMemory(szBodyOut, sizeof(TCHAR) * (uLen));
    }
    else
    {
        //Get size of current string, and the new one
        size_t sizeold = sizeof(TCHAR)*_tcslen(szBodyOut);
        size_t size = sizeof(TCHAR)*(_tcslen(pszTemp) + 5) + sizeold;
        
        //Save the old string
        TCHAR* szTemp = (TCHAR*)malloc(sizeold);
        memcpy(szTemp, szBodyOut, sizeold);

        //Allocate additional room for new string
        TCHAR* szNewOut = (TCHAR*)realloc(szBodyOut, size);
        CBRH((NULL != szNewOut), hr);

        szBodyOut = szNewOut; //Save new pointer

        //Clear it
        memset(szBodyOut, 0x00, size);
        
        //Copy old string, delete temp one
        memcpy(szBodyOut, szTemp, sizeold);
        free(szTemp);
    }

    //Append object length
    //force this to 4 TCHARS
    uLenTemp = _tcslen(pszTemp);
    szBuffer[0] = _T('0');
    szBuffer[1] = _T('0');
    szBuffer[2] = _T('0');
    uChar = (uLenTemp < 0x1000) ? 1 : 0;
    uChar = (uLenTemp < 0x100)  ? 2 : uChar;
    uChar = (uLenTemp < 0x10)   ? 3 : uChar;
    _itot(uLenTemp, &(szBuffer[uChar]), BASE_HEX);
    _tcscat(szBodyOut, szBuffer);
        
    //Append object data
    _tcscat(szBodyOut, pszTemp);
    free(pszTemp);
    pszTemp = NULL;

    //Check if last SM in multipart, or just done
    if((emshi.uCurrPart == emshi.uNumParts) || (!emshi.fMultiPart))
    {
        //allocate room for string buffer
        *ppszOut = (TCHAR*)malloc(_msize(szBodyOut));
        CBRH((NULL != *ppszOut), hr);

        //Copy string buffer
        memcpy(*ppszOut, szBodyOut, _msize(szBodyOut));

        //free internal copy
        free(szBodyOut);

        //Write out number of objects processed
        *pNumObjects = uObjCount;

        //Set this so we will cleanup on exit
        emshi.fMultiPart = FALSE;
    }
    
Exit:

    if(FAILED(hr) || (!emshi.fMultiPart))
    {
        if(pszTemp)
        {
            free(pszTemp);
            pszTemp = NULL;
        }
        if(szBodyOut)
        {
            free(szBodyOut);
            szBodyOut = NULL;
        }

        //reset counters
        uObjCount = 0;
        uBaseOffset = 0;
    }

    return hr;
}

/******************************************************************************

    WriteEMSToBody - Write out EMS info to body of message 

    Params:
    szEMSData[in] - String to write to body
    szMessageClass[in] - Message class to set (optional)
    pMsg[in] - Message we're writing to
    uObjCount[in] - number of objects in data string
    Returns:

    Remarks:

******************************************************************************/
HRESULT WriteEMSToBody(LPCTSTR szEMSData, 
                       LPCTSTR szMessageClass, 
                       IMessage* pMsg, 
                       UINT uObjCount)
{
    HRESULT     hr          = S_OK;
    int         cbBody      = 0;
    int         iCount      = 0;
    SPropValue  rgProps[2];         //PR_MESSAGE_CLASS and PR_SUBJECT
    LPSTREAM    pStmBody    = NULL;
    DWORD       cbWritten   = 0;
    TCHAR       szBuffer[3] = _T("");
    BYTE        uChar       = 0x00;
    TCHAR*      pszBody     = NULL;

    //Validate params, szMessageClass can be NULL, then we just don't alter it
    ASSERT(NULL != szEMSData);
    ASSERT(NULL != pMsg);
    ASSERT(uObjCount);
    if((NULL == pMsg) || (NULL == szEMSData) || (0 >= uObjCount))
    {
        hr = E_INVALIDARG;
        goto Exit;
    }

    //Set message class if we have one
    if(NULL != szMessageClass)
    {
        rgProps[iCount].ulPropTag   = PR_MESSAGE_CLASS;
        rgProps[iCount].Value.lpszW = const_cast<LPTSTR>(szMessageClass);
        iCount++;
    }
    rgProps[iCount].ulPropTag   = PR_SUBJECT;
    rgProps[iCount].Value.lpszW = _T("SDK EMS SAMPLE");
    iCount++;
    
    //Open the body property
    if(FAILED(hr = pMsg->OpenProperty(PR_BODY, NULL, 0,
                        MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN*)&pStmBody)))
    {
        goto Exit;
    }

    //Calculate length of body
    cbBody = sizeof(TCHAR)*(_tcslen(szEMSData) + _tcslen(STR_EMSID) + 3);

    pszBody = (TCHAR*)malloc(cbBody);

    CBRH((NULL != pszBody), hr);
    ZeroMemory(pszBody, cbBody);

    //Append the GUID
    _tcscat(pszBody, STR_EMSID);

    //Append number of objects
    szBuffer[0] = _T('0');
    uChar = (uObjCount < 0x10) ? 1 : 0;
    _itot(uObjCount, &(szBuffer[uChar]), BASE_HEX);
    _tcscat(pszBody, szBuffer);

    //Append rest of data
    _tcscat(pszBody, szEMSData);

    //Write string to body property
    if(FAILED(hr = pStmBody->Write(pszBody, cbBody, &cbWritten)) ||
        (cbWritten != (DWORD)cbBody))
    {
        if(hr == S_OK)
        {
            hr = E_FAIL;
        }
        goto Exit;
    }
    
    //Commit the change and finish
    if(FAILED(hr = pStmBody->Commit(0)))
    {
        goto Exit;
    }

    //Set whatever props
    if(FAILED(hr = pMsg->SetProps(iCount, rgProps, NULL)))
    {
        goto Exit;
    }

Exit:
    if(pszBody)
    {
        free(pszBody);
    }
    if(pStmBody)
    {
        pStmBody->Release();
    }
    return hr;
}

/******************************************************************************

    CFactory::CFactory - C'TOR, called by the static method GetClassObject once
    it determines the type of object the factory will create

******************************************************************************/
CFactory::CFactory(const CFactoryData* pFData) :
m_cRef(1)
{
    //I'm the only one calling this so pFData shouldn't be NULL
    ASSERT(pFData);

    //Init the factory data info
    memcpy(&m_FactoryData, pFData, sizeof(CFactoryData));
}

/******************************************************************************

    CFactory::~CFactory - D'TOR, add whatever you might need here....

******************************************************************************/
CFactory::~CFactory()
{
    RETAILMSG(TRUE, (_T("CFactory - destroying self.")));
}

/******************************************************************************

    CFactory::QueryInterface - IUnknown implementation

    Interfaces implemented:
    IID_IUnknown
    IID_IClassFactory

******************************************************************************/
STDMETHODIMP CFactory::QueryInterface(const IID& iid, LPVOID *ppv)
{
    HRESULT hr = E_NOINTERFACE;

    //Validate params
    if(!ppv)
    {
        hr = E_INVALIDARG;
        goto Exit;
    }
    
    //Check if requested interface is supported
    if((IID_IUnknown == iid) || (IID_IClassFactory == iid))
    {
        //Yes it is
        *ppv = reinterpret_cast<LPVOID>(this);
    }
    else
    {
        //No it isn't
        *ppv = NULL;
    }

    if(*ppv) 
    {
        //Interface was obtained so ref count
        (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
        hr = S_OK;
    }
    
Exit:
    return hr;
}

/******************************************************************************

    CFactory::AddRef - IUnknown implementation, pretty standard

******************************************************************************/
ULONG CFactory::AddRef()
{
    RETAILMSG(TRUE, (_T("CFactory::AddRef->m_cRef is now %d\r\n"), m_cRef+1));
    return InterlockedIncrement(&m_cRef);
}

/******************************************************************************

    CFactory::Release - IUnknown implementation, pretty standard

******************************************************************************/
ULONG CFactory::Release()
{
    InterlockedDecrement(&m_cRef);
    RETAILMSG(TRUE, (_T("CFactory::Release->m_cRef is now %d\r\n"), m_cRef));
    
    int nLocal = m_cRef;    //make a copy in case we're destroyed

    if(!m_cRef) 
    {
        //Ref count is now 0, destroy ourselves
        RETAILMSG(TRUE, (_T("CFactory::Release -> CFactory Deleted!\r\n")));
        delete this; 
    }

    return nLocal; 
}

/******************************************************************************

    CFactory::GetClassObject - called by DllGetClassObject, this enables us to
    host muliple components using the same class factory (yippe!!)

    Params:
    clsid[in] - CLSID of object we're looking to create
    iid[in]   - id of interface we want in said object
    ppv[out]  - gets the class factory ready to create correct object

******************************************************************************/
HRESULT CFactory::GetClassObject(const CLSID& clsid, const IID& iid, void** ppv)
{
    HRESULT hr      = S_OK;
    int     iIndex  = 0;

    //Interface must be one of these
    if((IID_IUnknown != iid) && (IID_IClassFactory != iid))
    {
        hr = E_NOINTERFACE;
        goto Exit;
    }

    //Check listed components this dll can load and match against CLSID
    for(iIndex = 0; iIndex < g_iFactoryDataEntries; iIndex++)
    {
        //Get data for each listed component
        const CFactoryData* pFData = &g_rgFactoryData[iIndex];
        
        //Check if requested CLSID is a match
        if(pFData->IsClassID(clsid))
        {
            //Bingo, create a class factory for this component
            *ppv = reinterpret_cast<IUnknown*>(new CFactory(pFData));

            if(NULL == *ppv)
            {
                hr = E_OUTOFMEMORY;
            }
            goto Exit; //We're done either way
        }
    }
    hr = CLASS_E_CLASSNOTAVAILABLE;

Exit:
    return hr;
}

/******************************************************************************

    CFactory::CreateInstance - Creates an instance of a component hosted in the
    DLL.  At this point we have all the info we need to create the correct one.

    Params:
    pUnknownOuter[in]   - COM aggregation stuff, not allowed here
    iid[in]             - id if interface we want
    ppv[out]            - pointer to requested interface 

******************************************************************************/
STDMETHODIMP CFactory::CreateInstance(IUnknown* pUnknownOuter, 
                                      const IID& iid, void** ppv)
{
    HRESULT     hr              = S_OK;
    IUnknown*   pNewComponent   = NULL;

    //No aggregation
    if(pUnknownOuter)
    {
        hr = CLASS_E_NOAGGREGATION;
        goto Exit;
    }

    //Create the component
    //m_FactoryData is initialized in the constructor, by the time CFactory is
    //created it knows how to create each type of object
    if(FAILED(hr = m_FactoryData.CreateInstance(pUnknownOuter, &pNewComponent)))
    {
        RETAILMSG(TRUE, (_T("CFactory::CreateInstance - m_FactoryData.CreateInstance failed")));
        goto Exit;
    }

⌨️ 快捷键说明

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