Click here to Skip to main content
15,886,963 members
Articles / Programming Languages / C++
Article

Reading and Writing Messages in Outlook Express

Rate me:
Please Sign up or sign in to vote.
4.94/5 (44 votes)
27 Mar 20062 min read 656.4K   5.3K   105   252
This article was done to provide an example of IStoreNamespace / IStoreFolder.

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


Written By
Technical Lead http://www.nektra.com
Argentina Argentina
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 a custom software development company specialized in Outlook Plugin Development, Data Loss Prevention Solution Development and Windows Driver Development.

Comments and Discussions

 
AnswerRe: MESSAGEPROPS dwFlags purpose? Pin
Pablo Yabo13-Jul-06 5:35
professionalPablo Yabo13-Jul-06 5:35 
GeneralRe: MESSAGEPROPS dwFlags purpose? Pin
User 18873013-Jul-06 12:59
User 18873013-Jul-06 12:59 
QuestionCan this code be used with VB 6.0? Pin
kramg6-May-06 3:38
kramg6-May-06 3:38 
AnswerRe: Can this code be used with VB 6.0? Pin
Pablo Yabo10-May-06 3:07
professionalPablo Yabo10-May-06 3:07 
QuestionAccessing OE from a service. Pin
goebish10-Apr-06 2:42
goebish10-Apr-06 2:42 
AnswerRe: Accessing OE from a service. Pin
Pablo Yabo11-Apr-06 3:54
professionalPablo Yabo11-Apr-06 3:54 
AnswerRe: Accessing OE from a service. Pin
goebish11-Apr-06 22:25
goebish11-Apr-06 22:25 
GeneralRe: Accessing OE from a service. Pin
Klirik20-Apr-06 17:24
Klirik20-Apr-06 17:24 
I think you can try to use another interface - IMessageStore. You can initialize it using the absolute path (in terms of file system) to the folder which contains the .dbx files. For example (on my machine) it is "C:\Documents and Settings\Alexey\Local Settings\Application Data\Identities\{<some_guid>}\Microsoft\Outlook Express". After proper initialization you will have access to whole tree of OE's folders located in this file folder.

You can get the instance using simple call of CoCreateInstance:

IMessageStore* p_store = NULL;
...
HRESULT hr = ::CoCreateInstance(CLSID_MessageStore,NULL,CLSCTX_INPROC_SERVER,IID_IMessageStore,(void**)&store );
if (FAILED(hr) || (p_store == NULL)) return E_FAIL;

hr = p_store->Initialize(sz_path_to_dbx_folder);
...

Then you can use member functions:
EnumChildren - to enumerate folders,
OpenFolder - to open folder,
OpenSpecialFolder... and so on.

They works very like the ones from IStoreNamespace (actually these members of IStoreNamespace delegate their calls to IMessageStore). If you see, for example, OpenFolder (in difference with such member from IStoreNamespace) returns the pointer to IMessageFolder, instead of IStoreFolder - and also wait for parameter IMessageServer.

Actually you can use IMessageFolder as more general version of IStoreFolder.

hm... I think I can summ the knowledge of internal OE structures into standalone article here on CodeProject, how you think? :->

Below is the necessary declarations (they are non-official - so, it may contain misstypes; be careful!)

<br />
// {101A8FB9-F1B9-11d1-9A56-00C04FA309D4}<br />
DEFINE_GUID(CLSID_MessageStore, 0x101A8FB9, 0xF1B9, 0x11d1, 0x9A, 0x56, 0x0, 0xC0, 0x4F, 0xA3, 0x09, 0xD4);<br />
<br />
// {E883FC75-EC08-11D1-9A53-00C04FA309D4}<br />
DEFINE_GUID(IID_IMessageStore, 0xE883FC75, 0xEC08, 0x11D1, 0x9A, 0x53, 0x0, 0xC0, 0x4F, 0xA3, 0x09, 0xD4);<br />
<br />
struct tagMESSAGEINFO;<br />
typedef tagMESSAGEINFO MESSAGEINFO, __RPC_FAR *LPMESSAGEINFO;<br />
<br />
struct tagFINDINFO;<br />
struct tagGETCOUNTTYPE;<br />
struct tagAPPLYCHILDRENTYPE;<br />
struct tagMARK_TYPE;<br />
struct tagFOLDERSORTINFO;<br />
struct tagGETNEXTTYPE;<br />
struct tagROWMESSAGETYPE;<br />
struct tagRELATIVEROWTYPE;<br />
//struct tagADJUSTFLAGS;<br />
struct tagFINDNEXTFLAGS;<br />
struct tagFOLDER_OPTIONS;<br />
<br />
interface IListSelector;<br />
interface IMessageServer;<br />
interface IMessageTableNotify;<br />
<br />
typedef DWORD MESSAGEID__;<br />
typedef unsigned long FOLDERID__;<br />
typedef DWORD tagADJUSTFLAGS;<br />
<br />
interface IStoreCallback : public IUnknown<br />
{<br />
};<br />
<br />
struct HLOCK__;<br />
struct tagTABLEINDEX;<br />
//struct tagTRANSACTIONTYPE;<br />
struct tagRESULTLIST;<br />
struct tagFOLDERINFO;<br />
struct HROWSET__;<br />
struct HTRANSACTION__;<br />
typedef unsigned short ushort;<br />
typedef unsigned char uchar;<br />
<br />
interface IDatabaseNotify;<br />
interface IDatabaseProgress;<br />
interface IDatabase;<br />
interface IEnumerateFolders;<br />
interface IImnAccount;<br />
<br />
interface IMessageFolder;<br />
<br />
interface IMessageStore : public IUnknown<br />
// CLSID_MessageStore = {101A8FB9-F1B9-11d1-9A56-00C04FA309D4}<br />
// IID_IMessageStore = {E883FC75-EC08-11D1-9A53-00C04FA309D4}<br />
{<br />
	virtual HRESULT STDMETHODCALLTYPE Lock(HLOCK__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE Unlock(HLOCK__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE InsertRecord(void *);<br />
	virtual HRESULT STDMETHODCALLTYPE UpdateRecord(void *);<br />
	virtual HRESULT STDMETHODCALLTYPE DeleteRecord(void *);<br />
	virtual HRESULT STDMETHODCALLTYPE FindRecord(unsigned long,unsigned long,void *,unsigned long *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetRowOrdinal(unsigned long,void *,unsigned long *);<br />
	virtual HRESULT STDMETHODCALLTYPE FreeRecord(void *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetUserData(void *,unsigned long);<br />
	virtual HRESULT STDMETHODCALLTYPE SetUserData(void *,unsigned long);<br />
	virtual HRESULT STDMETHODCALLTYPE GetRecordCount(unsigned long,unsigned long *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetIndexInfo(unsigned long,char * *,struct tagTABLEINDEX *);<br />
	virtual HRESULT STDMETHODCALLTYPE ModifyIndex(unsigned long,char const *,struct tagTABLEINDEX const *);<br />
	virtual HRESULT STDMETHODCALLTYPE DeleteIndex(unsigned long);<br />
	virtual HRESULT STDMETHODCALLTYPE CreateRowset(unsigned long,unsigned long,struct HROWSET__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE SeekRowset(struct HROWSET__ *,enum  tagSEEKROWSETTYPE,long,unsigned long *);<br />
	virtual HRESULT STDMETHODCALLTYPE QueryRowset(struct HROWSET__ *,long,void * *,unsigned long *);<br />
	virtual HRESULT STDMETHODCALLTYPE CloseRowset(struct HROWSET__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE CreateStream(unsigned long *);<br />
	virtual HRESULT STDMETHODCALLTYPE DeleteStream(unsigned long);<br />
	virtual HRESULT STDMETHODCALLTYPE CopyStream(struct IDatabase *,unsigned long,unsigned long *);<br />
	virtual HRESULT STDMETHODCALLTYPE OpenStream(enum  tagACCESSTYPE,unsigned long,struct IStream * *);<br />
	virtual HRESULT STDMETHODCALLTYPE ChangeStreamLock(struct IStream *,enum  tagACCESSTYPE);<br />
	virtual HRESULT STDMETHODCALLTYPE RegisterNotify(unsigned long,unsigned long,unsigned long,IDatabaseNotify *);<br />
	virtual HRESULT STDMETHODCALLTYPE DispatchNotify(struct IDatabaseNotify *);<br />
	virtual HRESULT STDMETHODCALLTYPE SuspendNotify(struct IDatabaseNotify *);<br />
	virtual HRESULT STDMETHODCALLTYPE ResumeNotify(struct IDatabaseNotify *);<br />
	virtual HRESULT STDMETHODCALLTYPE UnregisterNotify(struct IDatabaseNotify *);<br />
	virtual HRESULT STDMETHODCALLTYPE LockNotify(unsigned long,struct HLOCK__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE UnlockNotify(struct HLOCK__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetTransaction(struct HTRANSACTION__ * *,enum  tagTRANSACTIONTYPE *,void *,void *,unsigned long *,struct tagORDINALLIST *);<br />
	virtual HRESULT STDMETHODCALLTYPE MoveFileA(unsigned short const *);<br />
	virtual HRESULT STDMETHODCALLTYPE SetSize(unsigned long);<br />
	virtual HRESULT STDMETHODCALLTYPE Repair(void);<br />
	virtual HRESULT STDMETHODCALLTYPE Compact(struct IDatabaseProgress *,unsigned long);<br />
	virtual HRESULT STDMETHODCALLTYPE HeapAllocate(unsigned long,unsigned long,void * *);<br />
	virtual HRESULT STDMETHODCALLTYPE HeapFree(void *);<br />
	virtual HRESULT STDMETHODCALLTYPE GenerateId(unsigned long *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetClientCount(unsigned long *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetFile(unsigned short * *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetSize(unsigned long *,unsigned long *,unsigned long *,unsigned long *);<br />
	virtual HRESULT STDMETHODCALLTYPE Initialize(LPCSTR pszPath);<br />
	virtual HRESULT STDMETHODCALLTYPE Validate(unsigned long);<br />
	virtual HRESULT STDMETHODCALLTYPE GetDirectory(int,LPSTR lpString1,int iMaxLength);<br />
	virtual HRESULT STDMETHODCALLTYPE Synchronize(FOLDERID__ *,unsigned long,struct IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE FindServerId(char const *,FOLDERID__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE CreateServer(IImnAccount *,ULONG,FOLDERID__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE CreateFolder(ULONG,tagFOLDERINFO *,IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE OpenSpecialFolder(FOLDERID__ *,IMessageServer *,uchar,IMessageFolder**);<br />
	virtual HRESULT STDMETHODCALLTYPE OpenFolder(FOLDERID__ *,IMessageServer *,ULONG,IMessageFolder**);<br />
	virtual HRESULT STDMETHODCALLTYPE MoveFolder(FOLDERID__ *,FOLDERID__ *,ULONG,IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE RenameFolder(FOLDERID__ *,char const *,ULONG,IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE DeleteFolder(FOLDERID__ *,ULONG,IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetFolderInfo(FOLDERID__ *,tagFOLDERINFO *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetSpecialFolderInfo(FOLDERID__ *,uchar,tagFOLDERINFO *);<br />
	virtual HRESULT STDMETHODCALLTYPE SubscribeToFolder(FOLDERID__ *,int,IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE HrSetNoSecUICallback(ULONG,long (*)(ULONG));<br />
	virtual HRESULT STDMETHODCALLTYPE UpdateFolderCounts(FOLDERID__ *,long,long,long,long);<br />
	virtual HRESULT STDMETHODCALLTYPE EnumChildren(FOLDERID__ *,int,IEnumerateFolders **);<br />
	virtual HRESULT STDMETHODCALLTYPE GetAdvise(ULONG *,ULONG *,IAdviseSink * *);<br />
};<br />
<br />
interface IMessageFolder : public IUnknown<br />
{<br />
	virtual HRESULT STDMETHODCALLTYPE Lock(HLOCK__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE Unlock(HLOCK__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE InsertRecord(void *);<br />
	virtual HRESULT STDMETHODCALLTYPE UpdateRecord(void *);<br />
	virtual HRESULT STDMETHODCALLTYPE DeleteRecord(void *);<br />
	virtual HRESULT STDMETHODCALLTYPE FindRecord(ULONG,ULONG,void *,ULONG *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetRowOrdinal(ULONG,void *,ULONG *);<br />
	virtual HRESULT STDMETHODCALLTYPE FreeRecord(void *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetUserData(void *,ULONG);<br />
	virtual HRESULT STDMETHODCALLTYPE SetUserData(void *,ULONG);<br />
	virtual HRESULT STDMETHODCALLTYPE GetRecordCount(ULONG,ULONG *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetIndexInfo(ULONG,char * *,tagTABLEINDEX *);<br />
	virtual HRESULT STDMETHODCALLTYPE ModifyIndex(ULONG,char const *,tagTABLEINDEX const *);<br />
	virtual HRESULT STDMETHODCALLTYPE DeleteIndex(ULONG);<br />
	virtual HRESULT STDMETHODCALLTYPE CreateRowset(ULONG,ULONG,HROWSET__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE SeekRowset(HROWSET__ *,tagSEEKROWSETTYPE,long,ULONG *);<br />
	virtual HRESULT STDMETHODCALLTYPE QueryRowset(HROWSET__ *,long,void * *,ULONG *);<br />
	virtual HRESULT STDMETHODCALLTYPE CloseRowset(HROWSET__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE CreateStream(ULONG *);<br />
	virtual HRESULT STDMETHODCALLTYPE DeleteStream(ULONG);<br />
	virtual HRESULT STDMETHODCALLTYPE CopyStream(IDatabase *,ULONG,ULONG *);<br />
	virtual HRESULT STDMETHODCALLTYPE OpenStream(tagACCESSTYPE,ULONG,IStream * *);<br />
	virtual HRESULT STDMETHODCALLTYPE ChangeStreamLock(IStream *,tagACCESSTYPE);<br />
	virtual HRESULT STDMETHODCALLTYPE RegisterNotify(ULONG,ULONG,ULONG,IDatabaseNotify *);<br />
	virtual HRESULT STDMETHODCALLTYPE DispatchNotify(IDatabaseNotify *);<br />
	virtual HRESULT STDMETHODCALLTYPE SuspendNotify(IDatabaseNotify *);<br />
	virtual HRESULT STDMETHODCALLTYPE ResumeNotify(IDatabaseNotify *);<br />
	virtual HRESULT STDMETHODCALLTYPE UnregisterNotify(IDatabaseNotify *);<br />
	virtual HRESULT STDMETHODCALLTYPE LockNotify(ULONG,HLOCK__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE UnlockNotify(HLOCK__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetTransaction(HTRANSACTION__ * *,tagTRANSACTIONTYPE *,void *,void *,ULONG *,tagORDINALLIST *);<br />
	virtual HRESULT STDMETHODCALLTYPE MoveFileA(ushort const *);<br />
	virtual HRESULT STDMETHODCALLTYPE SetSize(ULONG);<br />
	virtual HRESULT STDMETHODCALLTYPE Repair(void);<br />
	virtual HRESULT STDMETHODCALLTYPE Compact(IDatabaseProgress *,ULONG);<br />
	virtual HRESULT STDMETHODCALLTYPE HeapAllocate(ULONG,ULONG,void * *);<br />
	virtual HRESULT STDMETHODCALLTYPE HeapFree(void *);<br />
	virtual HRESULT STDMETHODCALLTYPE GenerateId(ULONG *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetClientCount(ULONG *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetFile(ushort * *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetSize(ULONG *,ULONG *,ULONG *,ULONG *);<br />
	virtual HRESULT STDMETHODCALLTYPE Initialize(IMessageStore *,IMessageServer *,ULONG,FOLDERID__ *);<br />
	virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(int);<br />
	virtual HRESULT STDMETHODCALLTYPE UpdateRegistry(int);<br />
	virtual HRESULT STDMETHODCALLTYPE GetFolderId(FOLDERID__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetMessageFolderId(MESSAGEID__ *,FOLDERID__ * *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetAdvise(ULONG *,ULONG *,IAdviseSink * *);<br />
	virtual HRESULT STDMETHODCALLTYPE OpenMessage(MESSAGEID__ *,ULONG,IMimeMessage * *,IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE SaveMessage(MESSAGEID__ * *,ULONG,ULONG,IStream *,IMimeMessage *,IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE HrSetNoSecUICallback(ULONG,long (*)(ULONG));<br />
	virtual HRESULT STDMETHODCALLTYPE SetMessageFlags(tagMESSAGEIDLIST *,tagADJUSTFLAGS *,tagRESULTLIST *,IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE CopyMessages(IMessageFolder *,ULONG,tagMESSAGEIDLIST *,tagADJUSTFLAGS *,tagRESULTLIST *,IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE DeleteMessages(ULONG,tagMESSAGEIDLIST *,tagRESULTLIST *,IStoreCallback *);<br />
	virtual HRESULT STDMETHODCALLTYPE ResetFolderCounts(ULONG,ULONG,ULONG,ULONG);<br />
	virtual HRESULT STDMETHODCALLTYPE IsWatched(char const *,char const *);<br />
	virtual HRESULT STDMETHODCALLTYPE GetDatabase(IDatabase * *);<br />
	virtual HRESULT STDMETHODCALLTYPE ConnectionRelease(void);<br />
	virtual HRESULT STDMETHODCALLTYPE ConnectionRelease1(void);<br />
	virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp1(int);<br />
};<br />

GeneralRe: Accessing OE from a service. Pin
sunil_200828-May-09 18:22
sunil_200828-May-09 18:22 
QuestionIMimeBodyW Pin
MorpheusX5-Apr-06 4:43
MorpheusX5-Apr-06 4:43 
AnswerRe: IMimeBodyW Pin
Klirik5-Apr-06 18:53
Klirik5-Apr-06 18:53 
GeneralRe: IMimeBodyW Pin
MorpheusX6-Apr-06 4:16
MorpheusX6-Apr-06 4:16 
QuestionGetting Selected message id? Pin
Advaitha4-Apr-06 23:21
Advaitha4-Apr-06 23:21 
AnswerRe: Getting Selected message id? Pin
Klirik6-Apr-06 2:25
Klirik6-Apr-06 2:25 
GeneralRe: Getting Selected message id? Pin
Klirik6-Apr-06 6:22
Klirik6-Apr-06 6:22 
GeneralRe: Getting Selected message id? Pin
junmalv15-Aug-06 21:33
junmalv15-Aug-06 21:33 
GeneralRe: Getting Selected message id? Pin
Klirik16-Aug-06 3:28
Klirik16-Aug-06 3:28 
GeneralRe: Getting Selected message id? Pin
junmalv16-Aug-06 5:29
junmalv16-Aug-06 5:29 
GeneralRe: Getting Selected message id? Pin
Klirik16-Aug-06 19:20
Klirik16-Aug-06 19:20 
QuestionRe: Getting Selected message id? Pin
caywen25-Apr-08 6:10
caywen25-Apr-08 6:10 
GeneralRe: Getting Selected message id? Pin
Klirik27-Apr-08 1:41
Klirik27-Apr-08 1:41 
GeneralRe: Getting Selected message id? Pin
caywen29-Apr-08 7:30
caywen29-Apr-08 7:30 
AnswerRe: Getting Selected message id? Pin
kilt13-Apr-09 2:22
kilt13-Apr-09 2:22 
GeneralRe: Getting Selected message id? Pin
gnxfiles10-Nov-07 14:35
gnxfiles10-Nov-07 14:35 
AnswerRe: Getting Selected message id? Pin
Klirik10-Dec-07 5:34
Klirik10-Dec-07 5:34 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.