Click here to Skip to main content
Click here to Skip to main content

Reading and Writing Messages in Outlook Express

By , 27 Mar 2006
 
Prize winner in Competition "MFC/C++ Nov 2004"

Sample Image - Outlook_Express_Messages.jpg

Table of contents

Introduction

The application has the following features:

  1. List local folders.
  2. Create / rename / delete local folder.
  3. List messages of a local folder.
  4. Get message properties.
  5. Get message source.
  6. Create / copy / move / delete messages.
  7. Mark messages as Read or Unread.
  8. List body properties or headers.
  9. Get / set property values.
  10. Navigate body structure.
  11. Get / set body content.
  12. Insert bodies.
  13. List / add / remove attachments.

Using this Code

This code was written to provide an initial example of the IStoreFolder / IStoreNamespace classes. Then, an example of IMimeMessage / IMimeMessageTree / IMimeBody / IMimePropertySet was added to the application. The idea of this article is to document, with a complete example, all these interfaces to show how Outlook Express storage could be accessed.

In the initial dialog, all the local folders of the main identity are listed to let the user modify them. In the message dialog, you will see all the messages of the selected folder. Identifying the message source and other operations can be done here. In the 'Bodies' dialog, you will be able to view the message structure and modify it.

Points of Interest

List local folders:

// add all the folders to the list box recursively
void CDemoDlg::AddFolders(STOREFOLDERID dwFolderId)
{
    FOLDERPROPS props;
    HENUMSTORE hEnum;
    int nIndex;

    hEnum = NULL;

    // set the size of the structure
    // or the function return error
    props.cbSize = sizeof(FOLDERPROPS);

    HRESULT hr = 
      m_pStoreNamespace->GetFirstSubFolder(dwFolderId, 
      &props, &hEnum);

    while(SUCCEEDED(hr) && hr != 
               S_FALSE && hEnum != NULL) {
        nIndex = m_listFolder.AddString(props.szName);

        if(nIndex != LB_ERR && nIndex != LB_ERRSPACE) {
            // set the folder id as the data of the item
            m_listFolder.SetItemData(nIndex, props.dwFolderId);

            // add children of this folder too
            AddFolders(props.dwFolderId);
        }

        hr = m_pStoreNamespace->GetNextSubFolder(hEnum, &props);
    }

    // close the enum
    if(hEnum) {
        m_pStoreNamespace->GetSubFolderClose(hEnum);
    }
}

List messages of a folder:

//List messages of folder and add 
//all 'Subject' and 'From' to the list box
MESSAGEPROPS msgProps;
HENUMSTORE hEnumMsg;
CString item;
int nIndex;

hEnumMsg = NULL;

// set the size of the structure
// or the function return error
msgProps.cbSize = sizeof(MESSAGEPROPS);

// as we want the subject and other
// staff we get all the properties.
// you can use MSGPROPS_FAST as first parameter
// to get only a few properties of the message.
HRESULT hr = m_pStoreFolder->GetFirstMessage(0,
                                             0,
                                             MESSAGEID_FIRST,
                                             &msgProps,
                                             &hEnumMsg);

while(SUCCEEDED(hr) && hr != S_FALSE) {
    item = msgProps.pszDisplayFrom;
    item += _T("      ");
    item += msgProps.pszNormalSubject;

    // message subject and from is displayed in the list box.
    // data of each item is the message id.
    nIndex = m_listMsg.AddString(item);

    if(nIndex != LB_ERR && nIndex != LB_ERRSPACE) {
        m_listMsg.SetItemData(nIndex, msgProps.dwMessageId);
    }

    // free the message properties
    // as they are allocated by IStoreFolder.
    m_pStoreFolder->FreeMessageProps(&msgProps);

    hr = m_pStoreFolder->GetNextMessage(hEnumMsg, 
                                   0, &msgProps);
}

// close the enum
if(hEnumMsg) {
    m_pStoreFolder->GetMessageClose(hEnumMsg);
}

Display the source of a message:

// this function displays the source
// of the selected message in the list box
void CMsgDlg::OnView()
{
    ULONG ulReaded = 0;
    int nIndex;
    STOREFOLDERID dwSelMsg;
    HRESULT hr;
    IStream *pTextStream;
    char buffer[4096];

    // Get selected folder id
    nIndex = m_listMsg.GetCurSel();
    if(nIndex == LB_ERR) {
        MessageBox(_T("Select a message first."), 
                   _T("Demo Error"));
        return;
    }

    dwSelMsg = m_listMsg.GetItemData(nIndex);

    // create a IStream from the message
    hr = m_pStoreFolder->OpenMessage(dwSelMsg, 
         IID_IStream, (VOID **) &pTextStream);
    if(FAILED(hr)) {
        MessageBox(_T("Error opening message."), 
                   _T("Demo Error"));
        return;
    }

    CMsgSrcDlg msgSrcDlg;

    // read all the message
    do {
        hr = pTextStream->Read(buffer, 
             sizeof(buffer)-1, &ulReaded);

        if(FAILED(hr)) {
            MessageBox(_T("Error reading message."), 
                       _T("Demo Error"));
        }
        else {
            buffer[ulReaded] = 0;

            msgSrcDlg.AddMessageSource(buffer);
        }
    } while(SUCCEEDED(hr) && ulReaded != 0);

    if(SUCCEEDED(hr)) {
        // display message
        msgSrcDlg.DoModal();
    }

    pTextStream->Release();
}

Create a message in a folder:

IStream *newMail = NULL;
MESSAGEID msgId;
HRESULT hr;
ULONG len;
CString msgSource;

// Set msgSource to contain
// the source of the new message
...

// Create the IStream to write the new message
// this function returns the id of the new message
hr = m_pFolder->CreateStream(0, 0, &newMail, &msgId);
if(FAILED(hr)) {
    MessageBox(_T("Cannot Create Stream."), 
               _T("Demo Error"));
    return;
}

// write message source in the IStream
hr = newMail->Write((const char *) msgSource, 
     msgSource.GetLength(), &len);
if(FAILED(hr)) {
    MessageBox(_T("Cannot Write message."), 
               _T("Demo Error"));
    newMail->Release();
    return;
}

// Commit the IStream in the folder
// and use the returned msgId
hr = m_pFolder->CommitStream(0, 0, 0, 
                  newMail, msgId, NULL);
if(FAILED(hr)) {
    MessageBox(_T("Cannot Commit Stream."), 
               _T("Demo Error"));
    newMail->Release();
    return;
}

// release the IStream
newMail->Release();

List body properties:

// add property names to the combo box
// first get IMimeMessage interface
// using IStoreFolder and the message id.
hr = pFolder->OpenMessage(msgId,
                          IID_IMimeMessage,
                          (LPVOID*) &m_pMimeMsg);
if(FAILED(hr)) {
    OutputDebugString("CMessageTreeDlg::"
             "SetMessage: OpenMessage.\n");
    return;
}

// get root body of the message.
hr = m_pMimeMsg->GetBody(IBL_ROOT, 0, &m_hCurBody);
if(FAILED(hr)) {
    OutputDebugString("OEMessage::SetMessage:"
                      " Cannot get root body.\n");
    return;
}

...

// bind the body to the IMimePropertySet interface.
hr = m_pMimeMsg->BindToObject(m_hCurBody,
     IID_IMimePropertySet, (LPVOID *) &m_pPropertySet);
if(FAILED(hr)) {
    OutputDebugString("OEMessage::UpdateBodyInfo:"
           " BindToObject IID_IMimePropertySet.\n");
    return;
}

...

IMimeEnumProperties *pEnum = NULL;
ENUMPROPERTY eProp = {0};
ULONG cFetched;
HRESULT hr;

m_propNames.ResetContent();

// enum properties of the body.
hr = m_pPropertySet->EnumProps(0, &pEnum);
if(FAILED(hr)) {
    OutputDebugString("OEMessage::"
          "FillCombo: EnumProps.\n");
    return;
}

hr = pEnum->Next(1, &eProp, &cFetched);

while(SUCCEEDED(hr) && hr != S_FALSE) {
    m_propNames.AddString(eProp.pszName);

    hr = m_pAllocator->FreeEnumPropertyArray(1,
                                    &eProp, FALSE);
    if(FAILED(hr)) {
        OutputDebugString("OEMessage::FillCombo:"
                          " FreeEnumPropertyArray.\n");
    }

    hr = pEnum->Next(1, &eProp, &cFetched);
}

if(pEnum) {
    pEnum->Release();
}

List attachments:

ULONG attachCount, i, j;
HBODY *bodyAttachs = NULL;
HRESULT hr;
IMimeBody *pMimeBody;
LPSTR display;
int nItem;

m_attachs.ResetContent();

hr = m_pMimeMsg->GetAttachments(&attachCount,
                                   &bodyAttachs);
if(FAILED(hr)) {
    MessageBox(_T("Cannot get attachments:")
       _T(" GetAttachments."), _T("Demo Error"), MB_OK);
    return;
}

// keep only bodies of type IBT_ATTACHMENT.
for(i=0; i<attachCount;) {
    hr = m_pMimeMsg->IsBodyType(bodyAttachs[i],
                                  IBT_ATTACHMENT);
    if(hr != S_OK) {
        for(j=i+1; j<attachCount; j++) {
            bodyAttachs[j-1] = bodyAttachs[j];
        }

        attachCount--;
    }
    else {
        // for the attachments, get display
        // name of the body to add to the listbox.
        hr = m_pMimeMsg->BindToObject(bodyAttachs[i],
                                      IID_IMimeBody,
                                      (LPVOID *) &pMimeBody);
        if(SUCCEEDED(hr)) {
            hr = pMimeBody->GetDisplayName(&display);
            if(SUCCEEDED(hr)) {
                nItem = m_attachs.AddString(display);
                m_attachs.SetItemData(nItem,
                          (DWORD) bodyAttachs[i]);

                CoTaskMemFree(display);
            }
        }

        i++;
    }
}

if(bodyAttachs) {
    CoTaskMemFree(bodyAttachs);
}

Get body content:

while(1) { // just to save code!
    // bind body handle to a IMimeBody interface.
    hr = m_pMimeMsg->BindToObject(m_hCurBody,
                                  IID_IMimeBody,
                                  (LPVOID *) &pMimeBody);
    if(FAILED(hr)) {
        OutputDebugString("CMessageTreeDlg::"
             "UpdateBodyInfo: BindToObject\n");
        break;
    }

    ...

    encType = IET_BINARY;
    m_isTextBody = FALSE;

    m_cntType = GetContentType(m_hCurBody);

    // if the body is a 'text' treat as a text.
    // Otherwise, read it as a buffer char
    // by char.
    if(m_cntType.Find(_T("text")) == 0) {
        encType = IET_UNICODE;
        m_isTextBody = TRUE;
    }

    ...

    m_bodyContent = _T("");

    // Get body as a stream
    hr = pMimeBody->GetData(IET_UNICODE,
                            &pBodyStream);
    if(FAILED(hr)) {
        OutputDebugString("OEMessage::GetBodyText: GetData\n");
        break;
    }

    // if it is a text when we read it it comes unicode.
    if(encType == IET_UNICODE) {
        // for text bodies
        do {
            // Read the IStream into our buffer
            hr = pBodyStream->Read(lpszwBody,
                                   sizeof(lpszwBody)-sizeof(WCHAR),
                                   &ulRead);
            if(FAILED(hr)) {
                OutputDebugString("OEMessage::GetBodyText: Read\n");
            }
            else if(ulRead != 0) {
                // Null terminate it
                lpszwBody[ulRead/2] = '\0';
                m_bodyContent += (WCHAR *) lpszwBody;
            }
        } while(ulRead != 0);
    }
    else {
        do {
            // Read the IStream into our buffer.
            // It can be binary so it could
            // be displayed truncated.
            hr = pBodyStream->Read(lpszBody,
                                   sizeof(lpszBody)-sizeof(char),
                                   &ulRead);
            if(FAILED(hr)) {
                OutputDebugString("OEMessage::GetBodyText: Read\n");
            }
            else if(ulRead != 0) {
                // Null terminate it
                lpszBody[ulRead] = '\0';
                m_bodyContent += lpszBody;
            }
        } while(ulRead != 0);
    }

    pBodyStream->Release();

    break;
}

if(pMimeBody) {
    pMimeBody->Release();
}

Set body content:

HRESULT hr;
ULONG ulLength, ulWritten;
BSTR bstr = NULL;
IStream *pStream = NULL;
IMimeBody *pMimeBody = NULL;
PROPVARIANT propValue;

UpdateData(TRUE);

while(1) {
    // Create a new stream to write in the new body
    hr = CreateStreamOnHGlobal(NULL,
                               TRUE,
                               &pStream);
    if(FAILED(hr)) {
        MessageBox(_T("Cannot set content:" )
            _T(" CreateStreamOnHGlobal."),
            _T("Demo Error"), MB_OK);
        break;
    }

    // compute the new body length + the
    // zero that terminates the string
    ulLength = m_bodyContent.GetLength() + 1;

    // there are better ways
    // to do it but this is the easiest
    bstr = m_bodyContent.AllocSysString();

    // write in the new body
    hr = pStream->Write((LPWSTR) bstr,
                        ulLength * sizeof(WCHAR),
                        &ulWritten);
    if(FAILED(hr)) {
        MessageBox(_T("Cannot set content: Write."),
                   _T("Demo Error"), MB_OK);
        break;
    }

    // Commit the stream
    hr = pStream->Commit(STGC_DEFAULT);
    if(FAILED(hr)) {
        MessageBox(_T("Cannot set content: Commit."),
                   _T("Demo Error"), MB_OK);
        break;
    }

    // bind body handle to IMimeBody interface
    hr = m_pMimeMsg->BindToObject(m_hCurBody,
                                  IID_IMimeBody,
                                  (LPVOID *) &pMimeBody);
    if(FAILED(hr)) {
        MessageBox(_T("Cannot set content:")
                _T(" Commit."), _T("Demo Error"), MB_OK);
        break;
    }

    CString priCon, secCon;

    propValue.vt = VT_LPSTR;

    // get content-type property to save the body
    hr = m_pMimeMsg->GetBodyProp(m_hCurBody,
         PIDTOSTR(PID_HDR_CNTTYPE), 0, &propValue);
    if(FAILED(hr) || hr == S_FALSE) {
        MessageBox(_T("Cannot set content:")
             _T(" GetBodyProp."), _T("Demo Error"), MB_OK);
        break;
    }

    // this property has the format
    // of 'primaryType/secondaryType'
    char *sep = strchr(propValue.pszVal, '/');

    if(sep == NULL) {
        MessageBox(_T("Cannot set content:")
             _T("Content Type error."),
             _T("Demo Error"), MB_OK);
        PropVariantClear(&propValue);
        break;
    }

    secCon = sep+1;
    *sep = 0;
    priCon = propValue.pszVal;

    PropVariantClear(&propValue);

    // save the data in this new stream
    // into the body using
    // the save conent-type it had before
    hr = pMimeBody->SetData(IET_UNICODE,
                            priCon,
                            secCon,
                            IID_IStream,
                            pStream);
    if(FAILED(hr)) {
        MessageBox(_T("Cannot set content: SetData."),
                   _T("Demo Error"), MB_OK);
        break;
    }

    break;
}

if(bstr) {
    ::SysFreeString(bstr);
}
if(pMimeBody) {
    pMimeBody->Release();
}
if(pStream) {
    pStream->Release();
}

License

You can use this freely, leaving the copyright notice at the top of the files.

History

  • 28-Dec-2004 - First released: IStoreFolder / IStoreNamespace.
  • 25-Mar-2006 - Update: IMimeMessage / IMimeMessageTree / IMimePropertySet / IMimeBody.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Pablo Yabo
Technical Lead http://www.nektra.com
Argentina Argentina
Member
Pablo Yabo is a Software Developer since he was young, specialized in system internals.
In 2003 years ago founded with Sebastian Wain a Company named Nektra specialized in Outlook Express and Outlook Plugin Development.
Now there is a new Windows Live Mail API 2011 / 2009 that works on all the platforms Windows 7, Vista and XP

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralHooking message store eventsmembergnxfiles21 May '08 - 11:55 
I'd like to modify a message when a user clicks Send button. I thought it would be easy by hooking IStoreFolder like it was described here in comments regarding IMessageList. But I see it's not possible to instantiate IStoreFolder using CoCreateInstance so I can't patch vftable of IStoreFolder and replace eg. CreateStream(). Any ideas?
GeneralChanges are not saved in reports in Windows Mailmemberv_klad8 Apr '08 - 11:52 
Hi,
 
why in Outlook Express for Windows XP all of changes in reports are saved,

void CMessageTreeDlg::OnButtonSaveChanges()
{
HRESULT hr;
hr = m_pMimeMsg->Commit(COMMIT_REUSESTORAGE);

and in Microsoft Windows Mail for Windows Vista m_pMimeMsg->Commit returns it is said no in access and no changes?
 
thank you
GeneralProblems with IMimeMessage::SetProp and IMimeMessage::SetBodyPropmemberVishwananda Hemadri9 Mar '08 - 23:24 
Hi,
 
I have a requirement to modify headers for every email that is sent using Outlook Express.   I use a hidden window in a DLL to receive WM_NEWMSGS notification on the special folder OUTBOX. Below code excerpt is used to modify the header after opening the mime message
 
     <code>hr = pFolder->OpenMessage(msgId, IID_IMimeMessage, (LPVOID*) &m_pMimeMsg);
     hr = m_pMimeMsg->GetBody(IBL_ROOT, 0, hBody);
     propValue.vt = VT_LPSTR;
     propValue.pszVal = (LPSTR) m_pAllocator->Alloc(5);
     strcpy(propValue.pszVal, "false");
     hr = m_pMimeMsg->SetBodyProp(hCurBody, "MyProperty1", NOFLAGS, &propValue);
     m_pAllocator->Free(propValue.pszVal);
 
     propValue.vt = VT_LPSTR;
     propValue.pszVal = (LPSTR) m_pAllocator->Alloc(5);
     strcpy(propValue.pszVal, "false");
     hr = m_pMimeMsg->SetBodyProp(hBody, "MyProperty2", NOFLAGS, &propValue);
     m_pAllocator->Free(propValue.pszVal);
 
     hr = m_pMimeMsg->Commit(COMMIT_REUSESTORAGE);</code>
 
The above code excerpt seems to be working fine for all mails, that contain an attachment lesser than 1meg.   How ever for attachments over 1meg this fails.
 
Can any one out here tell me what does Outlook Express do after the commit.   Is there any thing missing from the code above.
 
Regards,
Hemadri
QuestionCan you tell me what's wrong in the sample of MS?membercrystalicetpmc5 Mar '08 - 0:35 

Windows Mail Programming Examples -- Reading and Writing Message Content

Thank you very much!


 
Crystal.Ice

AnswerRe: Can you tell me what's wrong in the sample of MS?memberPablo Yabo5 Mar '08 - 1:46 
hello,
Can you tell me the issue you experience using the example?
Pablo
GeneralRe: Can you tell me what's wrong in the sample of MS?membercrystalicetpmc5 Mar '08 - 3:47 
I'm soory because my English is very poor
 
Modified sample as bleow
It can complie and run
But this line
 
   pFileStream->QueryInterface(IID_IMimeMessage, (LPVOID*) &pMimeMessage);
 
Occurse exception
 
I want load *.eml and get attachments to save to files only but I don't know how?
 
   IStream* pFileStream = NULL;
   IMimeMessage* pMimeMessage = NULL;
   PROPVARIANT var;
   var.vt = VT_LPSTR;
   var.pszVal = NULL;
   HBODY hbody = 0;
 
   // Open specified file and return an IStream interface.
   SHCreateStreamOnFile((LPCSTR)L"somefile.eml", STGM_WRITE, &pFileStream);
  
   // Get an IMimeMessage interface and use it to...
   //pFileStream->QueryInterface(IID_PPV_ARGS(&pMimeMessage));
   pFileStream->QueryInterface(IID_IMimeMessage, (LPVOID*) &pMimeMessage);
  
   // ...change the subject...
   pMimeMessage->SetProp((LPCSTR)PID_HDR_SUBJECT, 0, (LPCPROPVARIANT)L"Here is the new subject");
  
   // ...read the To line...
   pMimeMessage->GetProp((LPCSTR)PID_HDR_TO, 0, &var);
  
   // ...read the message body...
   pMimeMessage->GetTextBody(TXT_HTML, IET_UNICODE, &pFileStream, &hbody);
  
   // Release our IStream object.
   pFileStream->Release();
  
   // Release our IMimeMessage object.
   pMimeMessage->Release();
 
Crystal.Ice
GeneralRe: Can you tell me what's wrong in the sample of MS?memberPablo Yabo5 Mar '08 - 5:48 
Try loading pFileStream in a IMimeMessage object
 
CoCreateInstance(CLSID_IMimeMessage, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID*)&pMimeMsg);
pMimeMsg->Load(pFileStream);
GeneralRe: Can you tell me what's wrong in the sample of MS?membercrystalicetpmc5 Mar '08 - 8:22 
Thank you very much!
I'll try tomorrow. (because here are 03:21 AM)
 
test

GeneralRe: Can you tell me what's wrong in the sample of MS?membercrystalicetpmc6 Mar '08 - 4:24 

You are right! Thank you very much!!!

But It possable can't load Outlook Express save as *.eml files format, so, the line below pMimeMessage->Load can't return S_OK.

Thank you very much!!!
 

  HRESULT hr = S_OK;
 
  IStream* pFileStream = NULL;
  IMimeMessage* pMimeMessage = NULL;
  PROPVARIANT var;
  var.vt = VT_LPSTR;
  var.pszVal = NULL;
  HBODY hbody = 0;
 
  // Open specified file and return an IStream interface.
  hr = SHCreateStreamOnFile((LPCSTR)_T("somefile.eml"), STGM_WRITE, &pFileStream);
  // Get an IMimeMessage interface and use it to...
  //hr = pFileStream->QueryInterface(IID_PPV_ARGS(&pMimeMessage));
  //hr = pFileStream->QueryInterface(IID_IMimeMessage, (LPVOID*) &pMimeMessage);
	hr = CoCreateInstance(CLSID_IMimeMessage, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID*)&pMimeMessage);
	hr = pMimeMessage->Load(pFileStream);  
  // ...change the subject...
<s>  hr = pMimeMessage->SetProp((LPCSTR)PID_HDR_SUBJECT, 0, (LPCPROPVARIANT)_T("Here is the new subject"));
  
  // ...read the To line...
  pMimeMessage->GetProp((LPCSTR)PID_HDR_TO, 0, &var);
  
  // ...read the message body...
  hr = pMimeMessage->GetTextBody(TXT_HTML, IET_UNICODE, &pFileStream, &hbody);</s>
  
  // Release our IMimeMessage object.
  pMimeMessage->Release();
 
  // Release our IStream object.
  pFileStream->Release();
  
  return 0;

 
Crystal.Ice


QuestionHow to link at C# projectmemberap8211 Oct '07 - 23:07 
Hi,
is there a way to using this project, written in Vc++, with my
project write in C#.
 
I retreive ad error while adding a reference.
Why?
 
Tnky
AnswerRe: How to link at C# projectmemberPablo Yabo4 Feb '08 - 1:28 
Hi,
I didn't use it in C# and it wasn't thought for C# but you may use managed C++ to import this code.
P-
Questionthis demo can't modify the content of a mail in oe or winodws mail(vista)memberfangqing11 Sep '07 - 15:28 
click the "set content" Button or "delete" button or "save changes" button,the content of the mail currently operated doesn't change.I have a project that must
modify a mail's content via programming, any one have good solution to modify the content of a mail in oe or windows mail please email me ,my email is fangqing0827@126.com,my msn is fangqinghust@hotmail.com,thanks
AnswerRe: this demo can't modify the content of a mail in oe or winodws mail(vista)memberKlirik10 Dec '07 - 5:45 
There are no miracles: this is the way (i.e., providing the READ-ONLY message) how taking of message's interface is implemented according MSDN. Read carefully: for IStoreFoldet it _IS_ said that the message is read-only!
 
So, why the example of Pablo works? Because the docs is MSDN about this read-only is not actually true. I.e., it is spoken, that the message is read-only, but when you try to submit the changes, OE actually does it! I believe this is because it was hard for developer to manage different access rights to different messages since they are stored in one big database file, different parts of which just mapped into the address space as different messages.
 
In WinMail the situation is different - since now every message is stored in it's own physical .eml file (look at %appdata%\Local\Microsoft\Windows Mail\Local Folders\... etc.) - so, now this is no problem to really open the message as READ-ONLY, exactly as it is promised in MSDN. And I think this is very situation you met.
 
However, using some hacks (interface hooking) it is possible to change the flag of the file being opening from GENERIC_READ to GENERIC_WRITE. It helps in some situation with the exception: if the message simultaneously opened in the view pane of Windows Mail, you couldn't change it anyway, because of sharing violation. However it is possible to modify and commit changes in currently unvisible messages of Windows Mail.
QuestionModifying .. [modified]memberHStrix20 Aug '07 - 2:38 
Hi,
this is really a great solution Smile | :)
 
But I'm curious if it is possible to modify an existing message simular as in MS Outlook?
 
Thank you for any help ..
 

-- modified at 8:58 Tuesday 21st August, 2007
QuestionMail Access In Service Modemembersurez12 Aug '07 - 21:04 
Hi ,
I want to access Outlook express mails when the application is run in service mode.When i run the application in service mode it gives me some default folder list not the actual one.Please let me know if it is possible
 
Thanks in advance
 
Regards
Kris
QuestionHow get the access to IMAP folders? [modified]memberDieter_Kr20 Jul '07 - 1:37 
HRESULT hr = m_pStoreNamespace->OpenFolder(..., &pFolder);
hr is E_FAIL, and description is "Unspecified error".
It happens, if is the IMAP folders.
And it happens in OS Windows Vista.
How can I resolve that trouble?

And I have second question: how can I get information that is IMAP folders?
Thanks.
 
Dieter

GeneralWindows Mail: IStoreNamespace/IStoreFolder RegisterNotificationmemberbask198218 Jun '07 - 16:43 
Hi
Developping Windows Mail plugin on the new Vista, I have a problem with this function (that I don't have with others Windows OS and Outlook Express!) :
=> hr = m_pNamespace->RegisterNotification( 0, m_hWnd );
 
It doesn't succeed and return COM error : -2147467263 (E_NOTIMPL). One more thing: other methods works properly. Does anybody knows what is the trick here?
 
Best regards
GeneralBulk save attachments and replace with linkmemberbaworth18 May '07 - 17:14 
I would like to do a bulk save attachments on any folfer or folders in Outlook Express to hard drive but leave a mark in the email pointing to where the attachment went. Would be nice to be able to choose the attachment typeto operate on, say *.jpg or *.*, or *.whatever.
 
I'm not much of a coder and I've downloaded a couple of programs to save attachments but none leave a link behind. Just looking to reduce my mail file size but keep the info around and easily accessabile.
 
Doable?
 

 
B.Worth baworth@hotmail.com
QuestionIs there a way to have such functionality in C#memberaleccc2 May '07 - 3:41 
or using msoeapi.h in C#?? I want access to folders and messages in OE from C# and I have not any idea how to do this.Confused | :confused: Confused | :confused: Confused | :confused:
AnswerRe: Is there a way to have such functionality in C#memberPablo Yabo2 May '07 - 3:53 
Hi,
I don't know any example in C#. If you need a complete solution for C# I suggest visiting our product Nektra OEAPI
 
Regards
Pablo
GeneralCreate FoldermemberMember #292037814 Feb '07 - 10:18 
Hi..
 
I want to create folder in outlook express instead of create sub folder that u provide in the source code... so what I need to change in the code to create folder like Inbox,Outbox... not create sub folder...
I m waiting your reply

GeneralI want to save mail attachmentsmemberV.A24 Dec '06 - 23:33 
I want to save mail attachments, with the help of code. Plz help me...
 
VIPLAV AGARWAL

Questionhow can read the deleted mail from outlok expressmembernaveen padiyar10 Dec '06 - 18:46 
if u have some idea then give me , how we can read .dbx file and deleted mail from outlook express.
 
naveen padiyar

QuestionCan I read attachments in-memory and parse it to the stringmemberBParsi4 Dec '06 - 16:56 
Hi,
 
The article was very nice but it is in C++. Can i have sample code for Outlook bounced emails.
 
Here I'm posting sample code:
 
ApplicationClass myOutlookApplication = new ApplicationClass ();
NameSpace myNameSpace = myOutlookApplication.GetNamespace("MAPI");
object myMissing = System.Reflection.Missing.Value;
myNameSpace.Logon(ConfigData.MailServer as object, myMissing, false, true);
MAPIFolder theInbox = myNameSpace.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
 
for (int i=theInbox.Items.Count-1; i -1) ||
(senderEmail.IndexOf("mail delivery subsystem") > -1) ||
(subject.IndexOf("returned") > -1) )
{
Read attachments and look for specific string here..
}
 
..
 
thank you,
 
Regards
ParsiB
AnswerRe: Can I read attachments in-memory and parse it to the stringmemberBParsi4 Dec '06 - 16:57 
Also I need the code in C#.
 
Thank you.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 27 Mar 2006
Article Copyright 2004 by Pablo Yabo
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid