none
Using the OL14_MailItem::SetRTFBody() function in unmanaged C++ RRS feed

  • Question

  • Hello,

    I want to set the RTF Body of outlook e-mail message. But with the following code it is not working.

    <pre lang="x-cpp">OL14_MailItem* pMailItem = NULL;
    OL14_Application* pOLApp = (OL14_Application*)pOLApplication;
    if( pOLApp ) {
    	pMailItem = new OL14_MailItem( pOLApp->CreateItem( 0 ) );
    }
    
    ..............
    
    tagVARIANT varText;
    varText.vt = VT_BSTR;
    CString m_strTEXT = _T("");
    m_strTEXT = _T("{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard This is some {\\b bold} text.\\par}");
    CComBSTR bstrText( m_strTEXT.GetBuffer( m_strTEXT.GetLength() ) );
    m_strTEXT.ReleaseBuffer();
    varText.bstrVal = bstrText;
    pMailItem->SetRTFBody( varText );
    

    The code above is raising an COleDispatchException.
    Setting the Plaine Text body or the HTML body is working fine.


    Has anybody an idea what the problem could be? 

    regards,
    rgwerder

    Tuesday, January 24, 2012 1:40 PM

All replies

  • RTFBody property expects a variant array of byte, not a variant of type string.
    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Tuesday, January 24, 2012 2:59 PM
  • Could please help me to convert the CString into a Byte array in the code above.
    Because when I try to convert with the following code I the outlook crashes:

    tagVARIANT varText;
    varText.vt = VT_BYREF | VT_UI1;
    CString m_strTEXT = _T("");
    m_strTEXT = _T("{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard This is some {\\b bold} text.\\par}");
    varText.pbVal = (BYTE*)m_strTEXT.GetBuffer( m_strTEXT.GetLength() );
    pMailItem->SetRTFBody( varText );
    
     
    

    regards,
    rgwerdfer

    Tuesday, January 24, 2012 4:57 PM
  • Thank you very much for your answer and help.

    Now I am using the SafeArrayCreate and SafeArrayPutElement function.
    But I still get an COLEException. The error code is 0x80070057 which means E_INVALIDARG.
    My new code is:

    SAFEARRAYBOUND boundText;
    boundText.cElements = 1;
    boundText.lLbound = 0;
    LPSAFEARRAY psaText = SafeArrayCreate(VT_UI1, 1, &boundText);
    SafeArrayPutElement(psaText, 0, (BYTE*)m_strTEXT.GetBuffer( m_strTEXT.GetLength() ) );
    tagVARIANT varRtfText;
    varRtfText.vt = VT_ARRAY | VT_UI1;
    varRtfText.parray = psaText;
    pMailItem->SetRTFBody( varRtfText );
    

    Does anybody know what I am doing wrong?

    regards,
    rgwerder


    • Edited by rgwerder Wednesday, January 25, 2012 10:12 AM
    Wednesday, January 25, 2012 10:11 AM
  • You will need to call SafeArrayPutElement for each byte of the RTF data.

    Note that RTF can include binary data (including 0x0), so it is not a good idea to store RTF in a string, especialy a Unicode string.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!
    Wednesday, January 25, 2012 1:44 PM
  • Hello Dmitry,
    Thank you very much for your help.

    Now I have changed my code calling SafeArrayPutElement() for each BYTE.
    But I still get the same error.
    Here is my new code: 

    CString m_strTEXT = _T("{\\rtf1 Hello!\\par {\\i This} is a formated {\\b text}.\\par the end.}");
    SAFEARRAYBOUND boundText;
    boundText.cElements = m_strTEXT.GetLength();
    boundText.lLbound = 0;
    LPSAFEARRAY psaText = SafeArrayCreate(VT_UI1, 1, &boundText);
    for( long i = 0; i < m_strTEXT.GetLength(); i++ ){
    	BYTE byteChar = (BYTE)m_strTEXT.GetAt(i);
    	SafeArrayPutElement(psaText, &i, &byteChar );
    }
    tagVARIANT varRtfText;
    varRtfText.vt = VT_ARRAY | VT_UI1;
    varRtfText.parray = psaText;
    pMailItem->SetRTFBody( varRtfText );
    

    What I am doing wrong?
    Can you see any error in my code?

    kind regards,
    rgwerder
     

    Friday, January 27, 2012 7:41 AM
  • Without actually running it, looks perfectly fine to me.

    Aren't you suppord to pass a pointer to the variant when calling SetRTFBody though?

    pMailItem->SetRTFBody( &varRtfText );

     

    Can read the RTF body and then set it back? If that works, what is different about the variant returned by GetRTFBody?


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!
    Sunday, January 29, 2012 11:21 PM
  • Hello Dmitry,

    Thank you very much for your help.

    the parameter of the SetRTFBody is 'const VARIANT& newValue'.
    I have tried the following test code:

    VARIANT varTest;
    varTest = pMailItem->GetRTFBody();
    pMailItem->SetRTFBody( varTest );
    

    The test code gives the same COLEException 'E_INVALIDARG'.

    Best regards,
    rgwerder

    Monday, January 30, 2012 9:03 AM
  • Hmmm.. I can reproduce this. The following script (you can run it from OutlookSpy) always fails:

     

    set Msg = Application.ActiveExplorer.Selection.Item(1)
    Msg.RTFBody = Msg.RTFBody
    Msg.Save


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Monday, January 30, 2012 2:08 PM
  • Hi Rgwerder,

    I will help you involve others to help you. There might be some delay about the response. Appreciate your patience.
    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Wednesday, February 1, 2012 7:50 AM
  • I can only offer to use Redemption (which exposes RtfBody as a string property on all items) if that is an option...

     


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!
    Wednesday, February 1, 2012 2:04 PM
  • Hi,

    I've only dealt with the RTFBody property before from the VB.Net perspective, and that's documented here:

    2605734 Cannot change body of meeting request in Send and ItemSend events
    http://support.microsoft.com/default.aspx?scid=kb;EN-US;2605734

    It was a bit painful to implement and in the end the key problem was that the item variable had to be strongly typed. Offhand, I don't think we have any C++ code samples for this, but I'll do some more checking.


    Bill Jacob - Microsoft Customer Service & Support - Developer Messaging
    Sunday, February 5, 2012 4:15 PM
    Moderator
  • Hi,

    Sorry, but I haven't been able to find a C++ code sample for this. If the previous information is not enough to get you up and running, please open a support incident and Customer Service & Support can help you further with this.


    Bill Jacob - Microsoft Customer Service & Support - Developer Messaging

    Wednesday, February 15, 2012 10:19 PM
    Moderator