How to: Retrieve the Body of a Message in Compressed RTF and Convert It to Its Native Format

How to: Retrieve the Body of a Message in Compressed RTF and Convert It to Its Native Format

This code example in Microsoft C++ shows you how to use the exported Outlook function WrapCompressedRTFStreamEx to access the body of a message that is encapsulated in compressed RTF, and to obtain the body in its native format.

  //These are definitions for the WrapCompressedRTFStreamEx function.
typedef HRESULT (STDMETHODCALLTYPE WRAPCOMPRESSEDRTFSTREAMEX) (
    LPSTREAM lpCompressedRTFStream, CONST RTF_WCSINFO * pWCSInfo, LPSTREAM * lppUncompressedRTFStream, RTF_WCSRETINFO * pRetInfo);
typedef WRAPCOMPRESSEDRTFSTREAMEX *LPWRAPCOMPRESSEDRTFSTREAMEX;

HRESULT TestWrapCompressedRTFStreamEx(LPMESSAGE lpMsg) { HRESULT hRes = S_OK; LPSTREAM lpCompressed = NULL; LPSTREAM lpUncompressed = NULL; char szBody[1024] = {0}; ULONG ulRead = 0; RTF_WCSINFO wcsinfo = {0}; RTF_WCSRETINFO retinfo = {0}; LPSPropValue lpPropCPID = NULL;

retinfo.size = sizeof(RTF_WCSRETINFO);

wcsinfo.size = sizeof(RTF_WCSINFO);
wcsinfo.ulFlags = MAPI_NATIVE_BODY;
wcsinfo.ulOutCodePage = 0;

// Retrieve the value of the Internet code page.
// Pass this value to the WrapCompressedRTFStreamEx function.
// If the property is not found, the default is 0.
if(SUCCEEDED(hRes = HrGetOneProp(lpMsg, PR_INTERNET_CPID, &lpPropCPID)))
{
    wcsinfo.ulInCodePage = lpPropCPID->Value.l;
}

// Open the compressed RTF stream.
if(SUCCEEDED(hRes = lpMsg->OpenProperty(PR_RTF_COMPRESSED,
                                     &IID_IStream,
                                     STGM_READ | STGM_DIRECT,
                                     0,
                                     (LPUNKNOWN*)&lpCompressed)))
{

    // Notice that the WrapCompressedRTFStreamEx function has been loaded
    // by using the GetProcAddress function into pfnWrapEx.

    // Call the WrapCompressedRTFStreamEx function.
    if(SUCCEEDED(hRes = pfnWrapEx(lpCompressed,
                               &wcsinfo,
                               &lpUncompressed,
                               &retinfo)))
    {

        printf("Body's native type is: ");

        // Check what the native body type is.
        switch(retinfo.ulStreamFlags)
        {
        case MAPI_NATIVE_BODY_TYPE_RTF:
            printf("MAPI_NATIVE_BODY_TYPE_RTF\n");
            break;
        case MAPI_NATIVE_BODY_TYPE_HTML:
            printf("MAPI_NATIVE_BODY_TYPE_HTML\n");
            break;
        case MAPI_NATIVE_BODY_TYPE_PLAINTEXT:
            printf("MAPI_NATIVE_BODY_TYPE_PLAINTEXT\n");
            break;
        default:
            printf("UNKNOWN\n");
        }

        // Read the first 1,000 characters out of the stream.
        if(SUCCEEDED(hRes = lpUncompressed->Read(szBody, 1024, &ulRead)))
        {
            printf("First %d characters of the native body stream:\n%s\n", ulRead, szBody);
        }
    }
}

MAPIFreeBuffer(lpPropCPID);
if(lpUncompressed)lpUncompressed->Release();
if(lpCompressed)lpCompressed->Release();

return hRes;

}