Udostępnij za pośrednictwem


Getting Started with MAPI

Getting Started with MAPI

(update 3/22/2007 1:59pm: see comments for .NetCF equivalent)

 

I’m Jay Ongg, and I’m a developer for Mobile Devices at Microsoft. I’ve been in this division for a little over four years, and as part of my job, I work with OEMs and ISVs. I’m here to write some articles on how to do some useful Messaging tasks.

 

Messaging is one of the areas that developers have trouble with, partly due to lack of documentation or examples. In order to deal with Messaging stores on a Windows Mobile device, developers have to work with MAPI. Unfortunately, until you get used to it, MAPI isn’t an easy beast to tame.

What Messaging Accounts do I have?

 

One of the common questions that we have is, “how do I enumerate all the accounts on a device?” Often, the developer is looking for a particular account by name or with a particular property. I’ll enumerate the steps needed to print out the name of every account on the device.

 

These are the steps needed:

  1. Login to MAPI
  2. Obtain the table of message stores
  3. Iterate through every row in the table
    1. MessageBox each display name
  4. Log out of MAPI

 

OK, how do I do it?

Here is the function. I’ll break it down below …

#include <atlbase.h>

#include <cemapi.h>

#include <mapiutil.h>

#include <mapidefs.h>

#define CHR(x) if (FAILED(x)) { hr = x; goto Error; }

HRESULT DisplayMessageStores()

{

    HRESULT hr;

    CComPtr<IMAPITable> ptbl;

    CComPtr<IMAPISession> pSession;

    SRowSet *prowset = NULL;

    SPropValue *pval = NULL;

    SizedSPropTagArray (1, spta) = { 1, PR_DISPLAY_NAME };

   

    // Log onto MAPI

    hr = MAPILogonEx(0, NULL, NULL, 0, static_cast<LPMAPISESSION *>(&pSession));

    CHR(hr); // CHR will goto Error if FAILED(hr)

   

    // Get the table of accounts

    hr = pSession->GetMsgStoresTable(0, &ptbl);

    CHR(hr);

   

    // set the columns of the table we will query

    hr = ptbl->SetColumns ((SPropTagArray *) &spta, 0);

    CHR(hr);

   

    while (TRUE)

    {

        // Free the previous row

        FreeProws (prowset);

        prowset = NULL;

        hr = ptbl->QueryRows (1, 0, &prowset);

        if ((hr != S_OK) || (prowset == NULL) || (prowset->cRows == 0))

        {

            break;

        }

        ASSERT (prowset->aRow[0].cValues == spta.cValues);

        pval = prowset->aRow[0].lpProps;

        ASSERT (pval[0].ulPropTag == PR_DISPLAY_NAME);

        MessageBox(NULL, pval[0].Value.lpszW, TEXT("Message Store"), MB_OK);

    }

    pSession->Logoff(0, 0, 0);

Error:

    FreeProws (prowset);

    return hr;

}

The Breakdown

In this code snippet (as well as future ones), I’ll tend to use ATL smart pointers and the CHR macro a lot. The CHR macro essentially checks the input parameter for an HRESULT failure, and if it fails, goto Error. For the purposes of sample code, I’ll be using it rather than doing manual error checking.

Login to MAPI

    hr = MAPILogonEx(0, NULL, NULL, 0, static_cast<LPMAPISESSION *>(&pSession));

    CHR(hr); // CHR will goto Error if FAILED(hr)

Pretty straightforward. Log into MAPI and get a pointer to an IMAPISession

Obtain the table of message stores

    // Get the table of accounts

    hr = pSession->GetMsgStoresTable(0, &ptbl);

  CHR(hr);

Again, pretty straightforward.

 

Iterate through every row in the table

First we initialized a struct at the beginning of the function. This struct is used to set the columns of the output from the upcoming message stores table query.

 

    SizedSPropTagArray (1, spta) = { 1, PR_DISPLAY_NAME };

       …

    // set the columns of the table we will query

    hr = ptbl->SetColumns ((SPropTagArray *) &spta, 0);

    CHR(hr);

   

SizedSPropTagArray is a helper macro defined in mapidefs.h that creates a sized array. We assign it one element, with the value PR_DISPLAY_NAME, which is defined in mapitags.h. I’ll talk more about this later.

 

After we create the struct, we call IMAPITable::SetColumns to set the columns.

 

The actual iteration:

    while (TRUE)

    {

        // Free the previous row

        FreeProws (prowset);

        prowset = NULL;

        hr = ptbl->QueryRows (1, 0, &prowset);

        if ((hr != S_OK) || (prowset == NULL) || (prowset->cRows == 0))

        {

            break;

        }

       …

    }

This code iterates through every row in the message stores table. We query one row at a time. FYI, IMAPITable::QueryRows will only return a max of 10 rows. IMAPITable::QueryRows will also automatically increment the internal row counter, so subsequent invocations will get the next row.

 

MessageBox each display name

        ASSERT (prowset->aRow[0].cValues == spta.cValues);

        pval = prowset->aRow[0].lpProps;

        ASSERT (pval[0].ulPropTag == PR_DISPLAY_NAME);

After querying the row, we do some ASSERTs to check that we got the expected number of columns as well as the correct property. PR_DISPLAY_NAME is the property that the account name is in, and is of type TCHAR *. You can infer this from the definition in mapitags.h:

#define PR_DISPLAY_NAME PROP_TAG( PT_TSTRING, 0x3001)

 

The SPropValue struct contains a member, Value, which is a union of a bunch of different types. So we have to access the wide-string member of the union, and print it out:

        MessageBox(NULL, pval[0].Value.lpszW, TEXT("Message Store"), MB_OK);

 

The memory pointed to by lpszW is allocated by MAPI, and we need to free the rowset (when we re-enter the loop, as well as when we exit the function):

        // Free the previous row

        FreeProws (prowset);

Log out of MAPI

   pSession->Logoff(0, 0, 0);

The most complex part of the function :)

 

Building

Make sure that when you build your project, you link in cemapi.lib as well.

So what else can I do?

So far I’ve given you a function that prints out the message store names, but there are many properties that you can query for. A quick glance of mapitags.h will give you some tips. Don’t go writing at tags if you don’t know what they do though!

 

In future articles I’ll talk about more advanced topics, such as getting the message store pointer, and iterating through folders/messages.

 

Hope this article helps some of you out. Feel free to leave a comment if you have any questions or ideas for blog topics!

Comments

  • Anonymous
    March 21, 2007
    Cool article.    Now can you show us how to do that in managed :-)

  • Anonymous
    March 22, 2007
    ...haven't used C/C++ since college!!  Don't like arrows in my programming languages (or paragraphs for you COBOL folks - if you've learned to use the internet yet) Please post C# (if possible). Thanks!

  • Anonymous
    March 22, 2007
    It is better to write a wrapper for CEMAPI and add it into .net cf. Looking forward to use managed code to access message system on windows mobile in the next version of .net cf.

  • Anonymous
    March 22, 2007
    Yup, I'll post .Net version :).  The initial requests I get for this example are usually from OEMs or in-ROM ISVs (who are more familiar with C++ I suppose :) ).

  • Anonymous
    March 22, 2007
    OK, here's how you do it in C#: make sure you have added Microsoft.WindowsMobile.PocketOutlook to your project (you get this from the Windows Mobile 5 SDK). This is the equivalent function: using Microsoft.WindowsMobile.PocketOutlook; private void showAccounts(object sender, EventArgs e) {    OutlookSession session = new OutlookSession();    MessageBox.Show(session.SmsAccount.Name);    foreach (EmailAccount account in session.EmailAccounts)    {        MessageBox.Show(account.Name);    } } Hope this helps. Yeap, C# is way easier.  However note that in .NetCF, the SMS account is separate from the collection of E-mail accounts.

  • Anonymous
    March 22, 2007
    Thanks for the post. Keep'em coming. But could you go a little more into detail and cover what's not yet in the SDK docs, say, something about the databases used by MAPI, similar to the article by Werner "Menneisyys" Ruotsalainen on mail-related information? In particular, how could I troubleshoot the mystery of disappearing email accounts (after radio failure).

  • Anonymous
    March 22, 2007
    Henry, the databases used by MAPI are not going to be in the SDK docs because this gives us the flexibility to make changes as necessary.   Given that, however, about your bug... I've personally never seen or heard of this bug before, but you can start by using the function that I wrote above. If the account disappeared, it may help you troubleshoot a little bit.

  • Anonymous
    March 24, 2007
    The comment has been removed

  • Anonymous
    March 25, 2007
    I've read that Microsoft is going to make public the Outlook/Exchange protocol. Any chance of getting information about this with regards to MAPI on Windows Mobile? http://reddevnews.com/news/devnews/article.aspx?editorialsid=192

  • Anonymous
    March 25, 2007
    Bill, MAPI is designed for use with on-board messaging databases, not for network access.  So it's unlikely that MAPI will be extended to access the Outlook/Exchange protocol directly. At least, I haven't heard anything.

  • Anonymous
    March 26, 2007
    Thanks for the response Jay! Sorry, let me rephrase the question. Any chance of seeing how Windows Mobile populates these on-board messaging databases over the network by using the low level Outlook/Exchange protocol? We're writing a tool that will proxy this traffic. I realize from the article I referenced that a license will likely need to be acquired. Any help would be really appreciated.

  • Anonymous
    March 26, 2007
    Thanks Jay for this detailed note. You have suggested that folks should look at mapitags.h (and mapi.h) -- but the most confusion part is that which properties are available in what objects? For example, account name is in message store and not in message itself. There are numerous challenges in MAPI with Windows Mobiles. Appreciate you could cover some of them: Here is the non-exausted list:

  1. Dynamic menu insertion (one of the most complex jobs -- menus vanish when you change 'views', there is no good way of knowing which menu is being selected, sub-menus pose their own problems)
  2. Inserting menus for certain kinds of accounts
  3. Retrieving properties such as From, TO, CC/BCC in POP/Outlook accounts
  4. Retrieving message body (HTML, TEXT, MIME)
  5. Creating your own form and rendering HTML body
  6. Developing outlook plugin and establishing proper event notification etc. More later nitin
  • Anonymous
    March 26, 2007
    Bill, I am looking into your question - so far I haven't heard anything about APIs to be made public. Nitin - I have ideas for blog topics lined up along those lines.  I agree that if you don't know what you're looking for, mapitags.h isn't going to help. However, hopefully in my future articles I will answer.  I intend to cover:
  1. How to read the from/to/text of an SMS (and later on, a POP3/Outlook message. The latter uses a different property).
  2. How to add a menu extension (to use with the tool I write in #1). I don't understand what you mean by "developing outlook plugin".  What do you mean by Outlook plugin? a menu extension? Creating your own form and rendering an HTML body is something that is more advanced and there exist demos for, especially if you have the OEM Adaptation Kit.  I'm not sure if there is a demo in the SDK though.
  • Anonymous
    March 27, 2007
    The error handling in this should be an example of how NOT to handle errors. The CHR macro jumps to a label that is followed by a free. What really needs to be done before exiting is the POOM logoff, which is right before the label. So, we've actually jump right past the one thing that needs to be done to clean up. But wait, it gets better. The free after the error jump is for an item that is never allocated until after all uses of the CHR macro, so it never has any possible use where it is. This sample would be better without any error handling at all.

  • Anonymous
    March 27, 2007
    Matthew, The destructor of the IMAPISession would handle that Logoff anyway, so the Logoff call strictly isn't necessary. I included it for illustrative purposes. However, the last FreeProws() is actually necessary, otherwise there will be a leak. Note that the last iteration of the loop will obtain a rowset but not free it.

  • Anonymous
    March 28, 2007
    How would you forward a message using MAPI? Is there any C++ sample code? Thanks.

  • Anonymous
    March 28, 2007
    jayongg, My point about the FreeProws() is that it is needed after the while loop, but not in the error jump. Putting it there implies its needed in some way for cleaning up when there is an error, but it all cases there is a juimp there, prowset will always be NULL. Its good to know the logoff is automatic. In that case, you could just do a clean return in the macro rather than a goto and be done with it.

  • Anonymous
    March 28, 2007
    Hi Dorel, you can "forward" a message using MailComposeMessage and attach a body/subject - it will bring up a new compose form for the user to fill out. The user will still have to hit Send Hi Matthew. I see your point.  Without turning this into a blog about coding styles.. The CHR()/Error macro implies that all cleanup occurs at the end of the function. A developer can confidently know that any usage of rowset will be cleaned up at the end.  I agree that it isn't necessary in this case (because everything will get cleaned up in the loop).  For me, it's force of habit since it ensures that if I error out of the loop early, I won't leak any rowset.  It's kind of like a poor-man's C++ destructor for cleanup (for the purposes of this article there's no point in writing a class to release on destruction). Thanks for looking at the code though.

  • Anonymous
    March 29, 2007
    Hi Jay, I have tried MailComposeMessage(), bat cannot manage the attachments that are not downloaded yet on the device (and I don't want to download the attachments on the device). Beside that, I don't want to bother the user with a Message form , and to hit the Send button. I was looking for a MAPI function similar to IMessage::SubmitMessage( ULONG ulFlags ); This imaginary function would work perfectly for me: IMessage::ForwardMessage(ULONG ulFlags, LPADRLIST lpTos); What I want to achieve is to forward messages with attachments to a preset email address. The process would be triggered by the user clicking on a Menu Extension Item on Inbox: "Forward to my MSN account..." Is there any programmatically way to invoke Active Sync to send a "SmartForward" Cmd request to Exchange Active Sync? [for example:  POST /Microsoft-Server-ActiveSync?User=meme&DeviceId=4fa4&DeviceType=PocketPC&Cmd=SmartForward&ItemId=1:3&CollectionId=0a093-1d&SaveInSent=F HTTP/1.1] Thanks for your help.

  • Anonymous
    March 29, 2007
    Hi Dorel, What exactly have you tried so far?  So you are saying that IMessage::SubmitMessage would work, as long as it allowed you to specify a message to forward, correct? imaginary function: IMessage::ForwardMessage(ULONG ulFlags, LPADRLIST lpTos, DWORD cbEntryIdMessageOriginal, LPENTRYID pEntryIdMessageOriginal) ? Unfortunately there is no public way of doing this.  Here is the issues involved: Activesync messages with Smart Forwarding use a private property to store information about text and attachments.  If you need this public, you will have a stronger case if you have an OEM or operator who would desire this functionality. We can't just publicize this functionality because we haven't tested this property/scenario under all circumstances. I hope this helps. Frankly this does sound like a cool feature to have.

  • Anonymous
    March 30, 2007
    Hi Jay, Thanks for the clarification. I am going to enroll in one of the Microsoft ISV programs.

  • Anonymous
    April 11, 2007
    Whould you tell me how to using function IMAPITable::Restrict(...)? is there any C++ sample code for it?

  • Anonymous
    April 11, 2007
    Another problem is that we use xml to create new message account. So whould you please tell me if there is any other account type we can use besides "Email2" account type? Attached is our xml sample: <wap-provisioningdoc>   <characteristic type="EMAIL2">    ......   </characteristic> </wap-provisioningdoc>

  • Anonymous
    April 11, 2007
    Cloud, what are you trying to do with IMAPITable::Restrict? You can create "Email2" and "Sync" accounts via XML.  Future versions of Windows Mobile may support more.  What are you trying to do?

  • Anonymous
    April 12, 2007
    Hi jayongg,  I want to count all unread messages on inbox. for using XML, i just want to add a new message account,for example "MMS".  Thank you!

  • Anonymous
    April 12, 2007
    Cloud, you can't add an MMS account via the XML, only email accounts.  To create an MMS account you need to create a message store using MAPI. as for counting unread messages in an inbox, there is a MAPI property one the MAPI folder that will allow you to do this. looks this up in the SDK.

  • Anonymous
    April 24, 2007
    > To create an MMS account you need to create a message store using MAPI. Can you give a sequence of operations how to create, for example, MMS account? Let us suppose, we have a MMSTransport.dll -- empty analog of MAPI New Messaging Transport Sample. Then we register it, something like this: ATL::CRegKey mms_trans_key; mms_trans_key.Create( HKEY_LOCAL_MACHINE, _T("Software\Microsoft\Inbox\Svc\MMS") ); mms_trans_key.SetStringValue( _T("Name"), _T("MMS") ); mms_trans_key.SetStringValue( _T("DefMsgClass"), _T("IPM.xMMS") ); mms_trans_key.SetStringValue( _T("DLL"), _T("MMSTransport.dll") ); mms_trans_key.SetDWORDValue ( _T("Port"), 0 ); There are questions:

  1. where and when we should create a message store using ICEMAPISession::CreateMsgStore()?
  2. how to create MMS account and link it with this message store?
  3. what else we should make to view the results in builtin Messaging application GUI? Thank you and please excuse me for my bad english.
  • Anonymous
    April 24, 2007
    _random, in order to create an MMS account, you should do what you did above, but also set this reg key (found in snapi.h): //////////////////////////////////////////////////////////////////////////////// // MessagingMmsAccountName // Gets the name of the MMS messaging account. #define SN_MESSAGINGMMSACCOUNTNAME_ROOT HKEY_CURRENT_USER #define SN_MESSAGINGMMSACCOUNTNAME_PATH TEXT("System\State\Messages\MMS") #define SN_MESSAGINGMMSACCOUNTNAME_VALUE TEXT("Account Name") To answer your questions:
  1. Create message store as early as possible. Obviously you want to do it before the user creates an MMS message (or receives one). ideally on cold boot. Or as part of your cab file install.
  2. You will need to create a mail transport as in the sample. If you use the sample, it doesn't work?
  3. You will need to create message forms to hook this up with the Messaging GUI.  You will need to do this using native code. Have you looked in the SDK on this topic?
  • Anonymous
    April 24, 2007
    > _random, in order to create an MMS account, you should do what > you did above, but also set this reg key (found in snapi.h): For experiments, I created separate MMSInstaller.exe as some installer analog: int _tmain( int argc, _TCHAR* argv[] ){ Register_DLLs_and_AccountName(); CreateMMSAccount(); return 0; } I have added this code to Register_DLLs_and_AccountName() function: void Register_DLLs_and_AccountName() { // register MMSTransport.dll {...} // you already saw it (roughly) // register MMSForm.dll {...} // similar as above, I have no questions about it // register MMS Account Name, as you said ATL::CRegKey mms_account_key; mms_account_key.Create( SN_MESSAGINGMMSACCOUNTNAME_ROOT, SN_MESSAGINGMMSACCOUNTNAME_PATH ); mms_account_key.SetStringValue( _T("Account Name"), _T("MMS") ); } Then, I write CreateMMSAccount() function based on MSDN's samples: void CreateMMSAccount() { HRESULT hr = ::MAPIInitialize( NULL ); ASSERT( SUCCEEDED(hr) ); ICEMAPISession * pSession = NULL; hr = ::MAPILogonEx( 0, NULL, NULL, 0, (LPMAPISESSION *)&pSession ); ASSERT( SUCCEEDED(hr) ); IMsgStore * pMsgStore = NULL; hr = pSession->CreateMsgStore( _T("MMS"), &pMsgStore ); ASSERT( SUCCEEDED(hr) ); pMsgStore->Release(); hr = pSession->Logoff(0, 0, 0); ASSERT( SUCCEEDED(hr) ); pSession->Release(); pSession = NULL; ::MAPIUninitialize(); } > 1. Create message store as early as possible. Obviously you want to do > it before the user creates an MMS message (or receives one). ideally > on cold boot. Or as part of your cab file install. I performed the registrations with MMSInstaller.exe on PPC 5.0 Emulator. Then I made soft reset (to restart native messaging application). Nothing changes in the Messaging GUI... The only account I see is Outlook E-mail. What else I should make or, may be, there are some mistakes in samples above? > 2. You will need to create a mail transport as in the sample. > If you use the sample, it doesn't work? It works... but I don't understand why we need to create account with this schema (as it is described in Windows Mobile 5.0 Pocket PC SDKSamplesCPPWin32Transportdemoreadme.txt): "4) Create a new account: a) Menu->Tools->New Account. b) (E-mail setup 1/5) Enter an email address which will use your custom transport. Click the Next softkey." Why email address? I don't want any e-mail on MMS account :). > 3. You will need to create message forms to hook this up with the > Messaging GUI.  You will need to do this using native code. Have you > looked in the SDK on this topic? I created simple MMSForm.dll that does nothing except show MessageBox( "It works :)" ); in each method of the IMessageFormEx interface.

  • Anonymous
    April 25, 2007
    I would like to know how I can retrieve MMS attachments. On my device, when I list the message store I get only Activesync and SMS. So I suppose MMS are stored in the SMS store and indeed I can retrieve the MMS subject using the PR_SUBJECT property but nothing more. How can I get pictures/sounds, ... What is the MMS format and properties, nobody has been able to answer this simple question ...

  • Anonymous
    April 25, 2007
    Hi Mosfet, Unfortunately, OEMs can provide whatever MMS properties and store messages any way they want - Microsoft doesn't dictate that.  Therefore, MMS message information can be stored in any way. You can contact the MMS providers to find out how they store the data - I believe some might even have an SDK.

  • Anonymous
    April 25, 2007
    Hi, Jay. And what about me? ;) Is it possible to create not E-mail account (for example MMS) using MAPI and integrate it into Messaging GUI? My experiments reach a deadlock. And I can't find help in MSDN... Thank you. With the hope of your help, random.

  • Anonymous
    April 25, 2007
    Hi Random, have you tried using the CreateMsgStore API?  You will also need to create some registry keys - this should all be in the SDK.

  • Anonymous
    April 25, 2007
    Above I wrote about it. First, I call a function (in installer.exe) with this code (on PPC WM 5.0 Emulator): // register MMS Account Name, as you said ATL::CRegKey mms_account_key; mms_account_key.Create( SN_MESSAGINGMMSACCOUNTNAME_ROOT, SN_MESSAGINGMMSACCOUNTNAME_PATH ); mms_account_key.SetStringValue( _T("Account Name"), _T("MMS") ); Second, I call this function: void CreateMMSAccount() { HRESULT hr = ::MAPIInitialize( NULL ); ASSERT( SUCCEEDED(hr) ); ICEMAPISession * pSession = NULL; hr = ::MAPILogonEx( 0, NULL, NULL, 0, (LPMAPISESSION *)&pSession ); ASSERT( SUCCEEDED(hr) ); IMsgStore * pMsgStore = NULL; hr = pSession->CreateMsgStore( _T("MMS"), &pMsgStore ); ASSERT( SUCCEEDED(hr) ); pMsgStore->Release(); hr = pSession->Logoff(0, 0, 0); ASSERT( SUCCEEDED(hr) ); pSession->Release(); pSession = NULL; ::MAPIUninitialize(); } Then, I make soft reset of the Emulator (thinking it restarts Messaging application). Nothing changes in GUI... I don't know what is the account itself: registry key + some directories? I think that pSession->CreateMsgStore( _T("MMS"), &pMsgStore ) -- will create the Directory. Can you point the MSDN article, where this mechanizm is described? Thank you.

  • Anonymous
    April 25, 2007
    Forgot to say: all functions runs successfully. I was checked it.

  • Anonymous
    April 25, 2007
    some news: second call pSession->CreateMsgStore( _T("MMS"), &pMsgStore ); returns 0x80040301 -- this HRESULT value is unknown for Error Lookup tool and doesn't exists in CreateMsgStore method description in MSDN. I hope this result says something like "MsgStore with this name already exists". Isn't it?

  • Anonymous
    April 25, 2007
    Hi random, is there an email address I can reach you at? we should take this offline.

  • Anonymous
    April 28, 2007
    how do i get the list of messages present in Inbox/Drafts using Mapi and then read them individually?

  • Anonymous
    April 28, 2007
    Hi roohi, please take a look at this link for some info on doing what you're asking for: http://blogs.msdn.com/windowsmobile/archive/2007/04/23/practical-use-of-mapi.aspx

  • Anonymous
    April 29, 2007
    Great articles on Mobile MAPI, but I do have a couple of questions that I can't seem to find an answer to anywhere:

  1. If a message is only partially downloaded (ie has MSGSTATUS_PARTIAL set) what command or commands trigger the full download?  (the equivalent of opening pocket outlook and hitting message download, but programmatic)
  2. In WM6 there is now HTML mail support, so I want to display the HTML in say a WebBrowser control...works great except for one problem.  Embedded images (images with a CID tag) are not displayed correctly.  I can manually parse the HTML and after saving the embedded attachments to a temp file reroute the src= param however I was wondering if there was perhaps a callback to allow us to fill in the image bytes of an embedded image?
  • Anonymous
    April 29, 2007
    Hi Noel, Regarding HTML Mail - you probably will have to write your own event handler to work with the HTML control to deal with embedded images.  I thought there was a callback mechanism, but I haven't looked at that code in a while... Regarding MSGSTATUS_PARTIAL, downloading a whole message is actually more complicated than just setting a flag.  Depending on the transport, you have to think about downloading attachments, which is done different for HTML mail vs normal attachments, I believe.  With that said, this might work... try setting the MSGSTATUS_REMOTE_DOWNLOAD flag to start out, and MSGSTATUS_REMOTE_DOWNLOAD_ATTACH as well. If that doesn't work, it's hard for me to give any advice without knowing exactly what your app is doing. Thanks, Jay

  • Anonymous
    May 07, 2007
    Yes, I figured there was a call to download the rest of the message, the MSGSTATUS_PARTIAL flag is already set by the message (I'm simply reading in the message and seeing that it is set) I want to get the body and perhaps the attachments; I'll try setting the DOWNLOAD flags thanks.

  • Anonymous
    May 25, 2007
    I would really like to be able to change the automatic checking period for an email account. For example, have no automatic check in the evening and every half hour in the day. For activesync these properties are stored in the registry. So I suppose I am asking how do you programmatically change the check period of an email account. Cheers

  • Anonymous
    May 25, 2007
    Hi Chris, I assume when you say "email account" you mean POP/IMAP accounts.  Unfortunately, there isn't a concept of peak and non-peak schedules with POP/IMAP accounts - I don't believe this is in the UI.

  • Anonymous
    May 25, 2007
    This is true. I was refering to IMAP/POP. I was wondering if it were possible to programmatically set it and therefore, I could use the notification queue to give me the peak/off peak behaviour.

  • Anonymous
    May 25, 2007
    The comment has been removed

  • Anonymous
    May 27, 2007
    The comment has been removed

  • Anonymous
    May 29, 2007
    The comment has been removed

  • Anonymous
    May 30, 2007
    Hi Hima, you will need to use Windows Mobile to get the MAPI APIs. I don't think that Windows CE supports them.

  • Anonymous
    June 03, 2007
    The comment has been removed

  • Anonymous
    June 14, 2007
    Hi Jay, I 'm trying to use IMAPITable::Restrict function to filter messages in the inbox folder. but it returns E_INVALIDARGS as result. i'm not able to figure out where the problem is. here's code for ur reference. HRESULT FilterMessagesExt() { HRESULT         hRes; LPSRowSet       pRows = NULL; SRestriction    sres; SPropValue      spv; LPMAPIFOLDER    pFldr; LPMAPITABLE     pCTbl; ULONG lCount ; SRowSet *prowset = NULL; HRESULT hr = S_OK; SizedSPropTagArray(1,spt) = {1,PR_SENDER_NAME }; //this is my utility function to return the folder pFldr=OpenFolder(Inboxfolder); hRes = pFldr -> GetContentsTable(0,&pCTbl); // select columns first hRes = pCTbl->SetColumns((LPSPropTagArray)&spt,0);     // sort depends on result of Restrict, do first sres.rt = RES_PROPERTY; spv.ulPropTag =PR_SENDER_NAME ; spv.Value.lpszW = (LPWSTR)("Sharma, Kapil"); sres.res.resProperty.relop = RELOP_NE; sres.res.resProperty.ulPropTag =PR_SENDER_NAME; sres.res.resProperty.lpProp = &spv; //here hRes gets E_INVALIDARGS as result hRes = pCTbl->Restrict(&sres,TBL_BATCH); pCTbl->GetRowCount(0,&lCount); Please see if u can help.. thanks Kapil

  • Anonymous
    June 20, 2007
    Hi Jay, Off late i have been playing with windows mobile 5.0 apis mostly with the apis available with pocketoutlook namespace (C#). This is what i am trying to implement: I will be having a separate application that has similar  UI as the Email compose form along with additional controls. Once user clicks on save/send i want the EmailMessage to be saved in the "Outbox" folder. After looking to the managed apis i did not find any apis that allow me to deal with folders other then contacts, tasks and appointments. I also went through "SendMail" CPP example available with the sdk which does something similar to what i want. However i was wondering if this is possible in C#. Any help of guidance in this respect will be appreciated. -Amit

  • Anonymous
    June 25, 2007
    mathew, jay etc can anyone help  me in intercepting an sms and then using camera api to take picture using smartphone in windows mobile 5.0(using c#)

  • Anonymous
    June 26, 2007
    Hi jay it seems when reading the body of a email ppc2003 returns an empty string.. I am using evc++ and using the tag PR_BODY i can send you a copy of the source, just let me know where.

  • Anonymous
    June 26, 2007
    It seems if i create a email message and then read its body text, it works fine. But emails received , body text returns a empty string

  • Anonymous
    June 26, 2007
    Hi, the PR_BODY is a stream, not a string, so you will have to open a stream, not get the property.

  • Anonymous
    June 26, 2007
    Using this piece of code HRESULT hr = m_pMessage->OpenProperty(PR_BODY   ,&IID_IStream, STGM_READ, 0, (IUnknown**)&istream);

  • Anonymous
    June 27, 2007
    Hi Jay, i 'm using the code below, but restrict returns E_INVALIDARG as result. SPropValue spv; spv.ulPropTag=PR_SENDER_NAME; spv.Value.lpszA=(LPSTR)("1001000"); SRestriction srs; srs.rt=RES_PROPERTY; srs.res.resProperty.lpProp=&spv; srs.res.resProperty.ulPropTag=PR_SENDER_NAME; srs.res.resProperty.relop=RELOP_EQ; any idea why it behaves like that?? thanks

  • Anonymous
    June 28, 2007
    The comment has been removed

  • Anonymous
    June 28, 2007
    I want to send SMS, MMS and MAIL from my PocketPC. I am using Messaging Tutorial on MSDN ([msdn.microsoft.com]) and SendMail project sample from the SDK. I can send SMS and MAIL but I don't know how to send MMS? Thanks

  • Anonymous
    June 28, 2007
    This can vary... are you trying to open a form? if so, MailComposeMessage with the MMS account should suffice.  Otherwise you will need to work with the vendor of the MMS provider - Microsoft doesn't create the MMS client.

  • Anonymous
    June 28, 2007
    Arcsoft did't provided api,so I can but implement WapWsp protocol to send mms? Thanks

  • Anonymous
    June 28, 2007
    Can anyone help me with this problem? Thanks!

  • Anonymous
    July 01, 2007
    Hi jay It seems if i create a email message and then read its body text, it works fine. But emails received , body text is empty Using this piece of code HRESULT hr = m_pMessage->OpenProperty(PR_BODY   ,&IID_IStream, STGM_READ, 0, (IUnknown**)&istream); I am using pocket pc 2003 device

  • Anonymous
    July 02, 2007
    I have a MAPI application that gets notified when there is new mail coming. What I would like to do is automatically to accept/deny a meeting invite base based on some specific properties of the meeting invite message. I can check those mesage's properties, but I don't know how to do the accepting/denying. Could you let me know which MAPI interface should I use for this purpose? If it is possible, some small code would be great. Thanks, Rocky

  • Anonymous
    July 05, 2007
    Hi All, does anyone know how to retrieve properties such as CC,BCC,FROM,TO... in the compose email? I try to get ENTRY ID of the compose message but it always blank. Thanks, dzung249

  • Anonymous
    July 16, 2007
    Hello Jay, I would like to create a new message and put it into Inbox. Could you provide a work example of saving PR_BODY, PR_BODY_HTML and PR_RTF_COMPRESSED properties into Outlook Mobile's message. Thank you.

  • Anonymous
    July 18, 2007
    Hi Anton, PR_RTF_COMPRESSED is not public. PR_BODY and PR_BODY_HTML are both streams, not strings. You will need to open them into IStream's and proceed from there. Hope this helps!

  • Anonymous
    July 18, 2007
    Hello Jay, Actually I use sreams and I can put PR_BODY into Outlook Mobile on Windows Mobile 5.0. But I cannot put PR_BODY_HTML into it using the same approach. Please note, that on Outlook 2003 on PC this code works fine for both PR_BODY and PR_BODY_HTML as well as for PR_RTF_COMPRESSED (I used WrapCompressedRTF... function). Thank you.

  • Anonymous
    August 01, 2007
    Hello Jay, Could you advise something&

  • Anonymous
    August 01, 2007
    Hi, Is there any solution for how to read and write MMS... Thanks

  • Anonymous
    August 01, 2007
    Unfortunately, there's no way to guarantee reading and writing MMS.  Microsoft doesn't create MMS clients, we simply allow others to plug into our Messaging application.

  • Anonymous
    August 29, 2007
    Jay: I like to know if you plan to answer the question posted by Kapil about the problem of having E_INVALIDARGS in return in calling IMAPITable::Restrict   Below is the code posted by Kapil.  Would you kindly let us know what steps are missing or incorrect?  Thank you. ====================================== Kapil said:   Hi Jay, I 'm trying to use IMAPITable::Restrict function to filter messages in the inbox folder. but it returns E_INVALIDARGS as result. i'm not able to figure out where the problem is. here's code for ur reference. HRESULT FilterMessagesExt() { HRESULT         hRes; LPSRowSet       pRows = NULL; SRestriction    sres; SPropValue      spv; LPMAPIFOLDER    pFldr; LPMAPITABLE     pCTbl; ULONG lCount ; SRowSet *prowset = NULL; HRESULT hr = S_OK; SizedSPropTagArray(1,spt) = {1,PR_SENDER_NAME }; //this is my utility function to return the folder pFldr=OpenFolder(Inboxfolder); hRes = pFldr -> GetContentsTable(0,&pCTbl); // select columns first hRes = pCTbl->SetColumns((LPSPropTagArray)&spt,0);     // sort depends on result of Restrict, do first sres.rt = RES_PROPERTY; spv.ulPropTag =PR_SENDER_NAME ; spv.Value.lpszW = (LPWSTR)("Sharma, Kapil"); sres.res.resProperty.relop = RELOP_NE; sres.res.resProperty.ulPropTag =PR_SENDER_NAME; sres.res.resProperty.lpProp = &spv; //here hRes gets E_INVALIDARGS as result hRes = pCTbl->Restrict(&sres,TBL_BATCH); pCTbl->GetRowCount(0,&lCount); ==========================

  • Anonymous
    August 31, 2007
    hello, i had to hard reset my o2 xdaII wm2003 and after the reset, im unable to send/recieve sms's. when i go the messages, i only have an account for activesync, but no account for SMS. unfortunately, i cannot create one myself. my presumption is this feature is on SIM - no matter how many times i have put the sim in, i still dont have an sms account. now im thinking, if this has a dll for sms and im missing it in the windows folder. my service provider had no clue what i was talking bout. any help is greatly appreciated!! thanks in advance - navyn. (navynbs@gmail.com)

  • Anonymous
    October 11, 2007
    There is a problem in my smartphone. If i send a sms, my phone is cant work properly, or stuck in long time. Or recieve sms, error reporting in (were sorry about inconvienence..... problem with device.exe..... Please help me?

  • Anonymous
    October 15, 2007
    I have read this board through, But I can't find any effective solution in sending mms with MAPI. I know it can be sent through wap in  wm2003, however wapopen etc seems to work improperly. Any one can help me. thanks. If you have any suggestion, contract me with msn: bjtulan@hotmail.com thanks a lots.  

  • Anonymous
    October 18, 2007
    I encountered the same problem as Kapil, anyone have any idea?

  • Anonymous
    November 07, 2007
    how can I iterate through the collection of received sms?? thank you to all

  • Anonymous
    November 09, 2007
    I'm writing my own GUI for messaging. With native MAPI APIs, my module can browse through alll the message stores, folders and messages and take actions on them. But I could not find an API for sync (send/recv) request. Although IMailSyncHandler interface is provided, this interface is provided to the developers for transport development. May you tell me how a message application request the mail synchronization? Thanks.

  • Anonymous
    November 09, 2007
    Hi Jeff, There should be an API. Look for MailSyncMessages here: http://msdn2.microsoft.com/en-us/library/ms894668.aspx Thanks, Jay

  • Anonymous
    November 09, 2007
    Jay, Thanks a lot. Yeah, it is there. But somehow, when I browsedthrough MAPI functions and did not find it yesterday.

  • Anonymous
    November 14, 2007
    Hi Jay, How can I get the EntryID of a Subfolder(from its name) of the Inbox folder (or the EntryID of the "Deleted Items" folder)? If this has been answered anywhere, please just direct me there, but I could not find the answer so far. Thanks

  • Anonymous
    November 14, 2007
    Hi Hendrik, try this: from the message store, get the PR_IPM_SUBTREE_ENTRYID property, cast it to IMAPIFolder. The call IMAPIFolder::GetHierarchyTable, and for each entry in the table you can the PR_DISPLAY_NAME as well as boolean listing whether it has subfolders (PR_SUBFOLDERS).

  • Anonymous
    November 14, 2007
    Thanks Jay ... got it working like a charm ... and thanks for the very quick response.

  • Anonymous
    November 14, 2007
    Great! Hendrik, because what I wrote was a little complicated, if you can post some sample code for the benefit of the rest of the readers? :)

  • Anonymous
    November 15, 2007
    Sure ... error handling is not yet what it should be, but ... // ************************************************************************** // Function Name: OpenFolder // // Purpose: Open a folder by searching for its name // Arguments: // IN IMsgStore* pMsgStore - Message Store to search (already open) // IN LPCWSTR *fNameArray - ptr to array containing full path of folder //                               in Message Store, ie. {"Inbox", "Subfolder"} // IN ULONG cfNameLevel - The nuber of folders in fNameArray // OUT IMAPIFolder *pFolder - ptr to open folder if found and opened // Return Values:  HRESULT depending on success of MAPI operations //                 ... and S_FALSE if any part of pathname not found                   HRESULT OpenFolder(IMsgStore *pMsgStore, LPCWSTR *fNameArray, ULONG cfNameLevel, IMAPIFolder *pFolder) {    HRESULT hr;    SPropValue * rgprops = NULL;    ULONG rgTags[]       = {1, PR_IPM_SUBTREE_ENTRYID};    ULONG cCount         = 0;    ULONG level          = 0;    SRowSet *prowset     = NULL;    IMAPIFolder *pParentFolder;    static const SizedSPropTagArray (3, spta) = { 3, PR_DISPLAY_NAME, PR_ENTRYID, PR_SUBFOLDERS };    hr = pMsgStore->GetProps((LPSPropTagArray) rgTags, MAPI_UNICODE, &cCount, &rgprops);    if (FAILED(hr) || cCount != 1) {        goto Exit;    }    hr = pMsgStore->OpenEntry(rgprops[0].Value.bin.cb,                              (LPENTRYID)rgprops[0].Value.bin.lpb,                              NULL,                              0,                              NULL,                              (LPUNKNOWN *) &pParentFolder);    if (FAILED(hr)) {        goto Exit;    }    while(SUCCEEDED(hr)) {        IMAPITable  *ptbl = NULL;        hr = pParentFolder->GetHierarchyTable(0, &ptbl);        if (FAILED(hr)) {            goto Exit;        }        // set the columns of the table we will query        hr = ptbl->SetColumns((SPropTagArray *) &spta, 0);        if (FAILED(hr)) {            goto Exit;        }        bool found = false;        while (!found && SUCCEEDED(hr)) {            // Free the previous row            FreeProws (prowset);            prowset = NULL;            hr = ptbl->QueryRows (1, 0, &prowset);            if ((hr != S_OK) || (prowset == NULL) || (prowset->cRows == 0)) {                goto Exit;            }            if(!(prowset->aRow[0].cValues == spta.cValues)) {            continue;            }            SPropValue *pval = prowset->aRow[0].lpProps;            if(!(pval[0].ulPropTag == PR_DISPLAY_NAME)            || !(pval[1].ulPropTag == PR_ENTRYID)            || !(pval[2].ulPropTag == PR_SUBFOLDERS)) {            continue;            }            DEB((wchar_t *)fNameArray[level], (wchar_t *)pval[0].Value.lpszW);            if(!wcscmp(fNameArray[level], pval[0].Value.lpszW)) {                pParentFolder->Release();                hr = pMsgStore->OpenEntry(pval[1].Value.bin.cb,                                          (LPENTRYID)pval[1].Value.bin.lpb,                                          NULL,                                          0,                                          NULL,                                          (LPUNKNOWN *)&pParentFolder);                if(FAILED(hr)) {                    goto Exit;                }                found = true;                if(++level == cfNameLevel) {                    pFolder = pParentFolder;                    goto Exit;                } else if(!pval[2].Value.b) {                    hr = S_FALSE;                }            }        }        if(!found) {            hr = S_FALSE;        }        ptbl->Release();    } Exit:    FreeProws (prowset);    MAPIFreeBuffer(rgprops);    if(FAILED(hr)) MAPIFreeBuffer(pParentFolder);    return hr; }

  • Anonymous
    November 15, 2007
    The comment has been removed

  • Anonymous
    November 22, 2007
    hi, I can able to create an SMS inthe Message folder inthe Drafts and can send it. After sending the message It returns  " Message Sent"/.  How can i dissable them in coding. Can you give me point to do it.

  • Anonymous
    November 23, 2007
    Hi Selva, it is not possible to turn off that notification.

  • Anonymous
    January 17, 2008
    Hi jayongg, I would like to know how to read the from/to/text of an SMS. thanks.

  • Anonymous
    January 28, 2008
    How to remove the account picker and still have the account created?

  • Anonymous
    February 19, 2008
    I saw some questions by Anton above and I was trying to do the same thing.  I basically want to store and email body that is in HTML format.  I don't even see the PR_HTML flag in the SDK.  Can you please shed some light on how to store a message body in HTML format and have it properly rendered in Pocket Outlook ("Messaging" application on device). Thanks, Joe

  • Anonymous
    February 19, 2008
    Joe, you can write your HTML directly into the PR_BODY_HTML_A stream property. You may also need to set the MSGSTATUS_HAS_PR_BODY_HTML flag.

  • Anonymous
    February 20, 2008
    The SizedSSortOrderSet macro creates a named SSortOrderSet structure that contains a specified number of sort orders. SizedSSortOrderSet (_csort, _name) With first parameter value as 1 (one) it works fine.... But when I pass 2 as first parameter , it gives me error. I want to perform categorised sort. Can't we use 2 sort orders ? Early reply will be highly appreciable. Thanks.

  • Anonymous
    February 20, 2008
    The SizedSSortOrderSet macro creates a named SSortOrderSet structure that contains a specified number of sort orders. SizedSSortOrderSet (_csort, _name) With first parameter value as 1 (one) it works fine.... But when I pass 2 as first parameter , it gives me error. I want to perform categorised sort. Can't we use 2 sort orders ? Thanks.

  • Anonymous
    February 27, 2008
    Jay - thanks for the answer.  I am now able to display HTML email on my device.  I cannot find a way to create an email, on the device, in HTML format.  Is this even supported?

  • Anonymous
    February 27, 2008
    I forgot to mention that I am referring to using the "Messaging" application on the device to create my emails.

  • Anonymous
    March 09, 2008
    I met a problem: I use MailSyncMessages API in my code, and I do include "cemapi.h" and link with "cemapi.lib", but when link I still get link error like "error LNK2019: unresolved external symbol "long __cdecl MailSyncMessages(wchar_t const *,unsigned long)" (?MailSyncMessages@@YAJPB_WK@Z) referenced in function "public: long __cdecl CEMail::SyncMessages(class ATL::CStringT<wchar_t,class StrTraitMFC<wchar_t,class ATL::ChTraitsOS<wchar_t> > > const &)" (?SyncMessages@CEMail@@QAAJABV?$CStringT@_WV?$StrTraitMFC@_WV?$ChTraitsOS@_W@ATL@@@@@ATL@@@Z) 1>Windows Mobile 5.0 Pocket PC SDK (ARMV4I)ReleaseTestMail.exe : fatal error LNK1120: 1 unresolved externals". Does anyone know what I missed and how can I fix it? Thanks a lot!

  • Anonymous
    March 09, 2008
    Hi Bruce, you need to link to cemapi.lib.

  • Anonymous
    March 09, 2008
    Hi Jay, Yes, I do. I tried two ways: in the project link setting or use #pragma comment(lib, "cemapi.lib"), but I still got that link error. That's why confused me.

  • Anonymous
    March 21, 2008
    Bruce, I don't have the answer, but faced a similar problem with the samples for CEMAPI after applying SP1 for VS2005. I have found the same sample works fine for VS2008.

  • Anonymous
    March 25, 2008
    Hello, I need help with some iPAQs. We own approx. 100 x HP iPAQ 2210, 30 x HP iPAQ 2410 and 50 x HP iPAQ 2490 iPaqs. Were having trouble using MAPI to retrieve e-mails GUIDs in order to make remote configurations for our Sales Force Team. If we follow MSs documentation, the code works properly in Visual Studios emulator, but not in our equipment. We have found that the iPaqs have a different value for PR_CE_UNIQUE_STORE_ID when we query the property pRows->aRow 0 lpProps ePR_CE_UNIQUE_STORE_ID .ulPropTag (MS says it must be 0x81130048 but the iPaq returns another value). And even if we change this value to match iPaq`s one, the GUID returned does not points to a valid e-mail account and thus we cannot use it to manage them. We need to solve this ASAP, since we have a deadline from our Audit team and this problem is hindering the delivery of the solution. Please if someone have any idea how to solve it, please send me an e-mail: michelle.rosario@garoto.com.br Best Regards. Michelle Santos

  • Anonymous
    March 26, 2008
    Michelle, I asked a colleague and this is what he said: "The value of PR_CE_UNIQUE_STORE_ID should not be different for different devices. It’s more likely that the property query is returning a different proptag value because the property cannot be found. (I think the value is PT_ERROR.) From what I can tell, the property only exists on accounts that are created via CSP. Maybe they are configuring the accounts differently on the iPaqs than on the emulator?" Thanks, -Luis Cabrera

  • Anonymous
    March 31, 2008
    Hi Jay, I am also doing the same thing  like Random was doing and I also struck in the same way.I do not know how link the my MMSForm.dll with exsisting GUI , I am creating the registries under, HKEY_CURRENT_USER\Software\Microsoft\Inbox\MsgTypes\IPM\MMS I cannot able to see in the messaging menu and the respective Form dll is not getting loaded, is there anything more I need to do. I was referring the    SDK documents but I am getting confused. If you can give me some directions on this I will be greatful to you.

  • Anonymous
    March 31, 2008
    Varun, make sure that you have: HKLMSoftwareMicrosoftInboxSvc<service>MsgClasses has "IPM.MMS" = dword:1 set in addition make sure you have HKLMSoftwareMicrosoftInboxSvc<service> "name" and "dll" set your dll needs to implement FormFactoryEx.

  • Anonymous
    March 31, 2008
    hi jay As per SDK documents for registering the form dll "Registering Customized Messaging Forms " we need to register as per following way 1 To register the form as a message class 2 To register the list of supported messaging transports 3 To register the list of supported message classes For the above steps I am doing the following steps to register my dlls 1 To register the form as a message class HKEY_CURRENT_USERSoftwareMicrosoftInboxMsgTypesIPMMMS Name : MMS Dll  : MMSForm.dll GlyphInfo :INBOXGLYPHINFO igInfo (structure init with appropriate values) 2To register the list of supported messaging transports HKEY_LOCAL_MACHINESOFTWAREMicrosoftInboxSvcMMS Name : MMS DLL : MMSTransporter.dll UserCanCreate : 1 Port: 120 3 To register the list of supported message classes HKEY_LOCAL_MACHINESOFTWAREMicrosoftInboxSvcMMSMsgClasses IPM.MMS : 1 I am using the Form Dll which implement the FormFactoryEx api,which internally loads the MUI file and returns the appropriate HRESULT, we have already implemented the interfaces  IFormProviderEx::CreateComposeForm IFormProviderEx::CreateReadForm  in my form dll I want to is there anything which I might be missing or something else I need to do so that it can load my   form dll  

  • Anonymous
    March 31, 2008
    Varun, did you create an account that uses your MMS transport? you can use the email CSP to create one.

  • Anonymous
    March 31, 2008
    hi jay I also want to know after setting the new account as per Program FilesWindows CE Toolswce500Windows Mobile 5.0 Pocket PC SDKSamplesCPPWin32Transportdemoreadme.txt I tried to set a new account for MMS but unfortunately ther is no change in the messaging menu... what I need to do so that I can hook that messaging menu to insert the MMS as new menu and when user pressed that menu it will launch ComposerForm through MMSForm.dll If you have any clue or directions regarding this please suggest. regards varun

  • Anonymous
    March 31, 2008
    hi jay I also want to know after setting the new account as per Program FilesWindows CE Toolswce500Windows Mobile 5.0 Pocket PC SDKSamplesCPPWin32Transportdemoreadme.txt I tried to set a new account for MMS but unfortunately ther is no change in the messaging menu... what I need to do so that I can hook that messaging menu to insert the MMS as new menu and when user pressed that menu it will launch ComposerForm through MMSForm.dll If you have any clue or directions regarding this please suggest. regards varun

  • Anonymous
    March 31, 2008
    jay what do you mean by email CSP and i tried to create the account as mentioned in Program FilesWindows CE Toolswce500Windows Mobile 5.0 Pocket PC SDKSamplesCPPWin32Transportdemoreadme.txt I follow the steps which is mentioned in this txt, anything else which I need to do ? regards varun

  • Anonymous
    April 09, 2008
    How can i run this code in microsoftvisualstudio2008.. can u help me

  • Anonymous
    April 22, 2008
    is sms transport hardcoded? i want to change that transport but it seems always tpcutil.dll gets loaded! is there anyway to change that?

  • Anonymous
    April 22, 2008
    Look in HKLMSoftwareMicrosoftInboxSvcSms, value "Dll".  it is tpcutil.dll. If you wish to replace it, you can.

  • Anonymous
    April 22, 2008
    well i replace it but there is no effect! for example replace it to tpcuitllllll.dll,just meaningless dll,i guess this way sms sending/recieving ,moving sms's around should not work! but it works perfectly! i also checked that if it gets loaded by tmail.exe,and it seems anyway tmail.exe loads this dll! i didnt dig more because i saw this post,and then i came here! http://groups.google.com/group/microsoft.public.pocketpc.developer.networking/browse_thread/thread/535a64638157571a/2a040b4490d45e38?lnk=st&q=tpcutil+outgoing#2a040b4490d45e38 so,should i implement a dll and see if replacing it seems ok,or just dont waste my time? thanks

  • Anonymous
    May 21, 2008
    Hi jayongg It seems I am experiencing the same problems as random regarding account creation. I have created the registry keys, and then I attempt to create a message store, but CreateMsgStore() returns an error (E_INVALIDARG). Do you have any idea what could cause this? Thanks in Advance Registry key creation:


void RegisterVVMClient() {    HKEY hKey;    DWORD dwDisp;    long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, L"CLSID{BEB30194-AEAE-BFBF-CDCD-118CCE923125}\InProcServer32", 0, NULL, 0, 0, NULL, &hKey, &dwDisp);    DEBUG_INS->Print("RegisterVVMClientn");    if (lResult == ERROR_SUCCESS)    {        HMODULE hModule = GetModuleHandle(IMAGENAME);        if (hModule)        {            TCHAR szName[MAX_PATH];            if (GetModuleFileName(hModule, szName, ARRAYSIZE(szName)))            {                RegSetValueEx(hKey, NULL, 0, REG_SZ, (const BYTE *)szName, _tcslen(szName)*sizeof(TCHAR));                TCHAR szModel[] = L"Free";                RegSetValueEx(hKey, L"ThreadingModel", 0, REG_SZ, (const BYTE *)szModel, _tcslen(szModel)*sizeof(TCHAR));                RegCloseKey(hKey);            }        }    }    lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE, L"Software\Microsoft\Inbox\Svc\VVM", 0, NULL, 0, 0, NULL, &hKey, &dwDisp);    if (lResult == ERROR_SUCCESS)    {        DWORD dwValue = 1;        RegSetValueEx(hKey, L"{BEB30194-AEAE-BFBF-CDCD-118CCE923125}", 0, REG_DWORD, (const BYTE *)&dwValue, sizeof(DWORD));        RegCloseKey(hKey);    }    lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE, L"Software\Microsoft\Inbox\Svc\VVM\MsgClasses", 0, NULL, 0, 0, NULL, &hKey, &dwDisp);    if (lResult == ERROR_SUCCESS)    {        DWORD dwValue = 1;        RegSetValueEx(hKey, kszVVMMsgClass, 0, REG_DWORD, (const BYTE *)&dwValue, sizeof(DWORD));        RegCloseKey(hKey);    }    lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE, L"Software\Microsoft\Inbox\Svc\VVM_Transport", 0, NULL, 0, 0, NULL, &hKey, &dwDisp);    if (lResult == ERROR_SUCCESS)    {        TCHAR szName[] = L"VVM_Transport"; RegSetValueEx(hKey, L"Name", 0, REG_SZ, (const BYTE *)szName, _tcslen(szName)*sizeof(TCHAR)); TCHAR szDll[] = L"TV_Inbox.dll"; RegSetValueEx(hKey, L"DLL", 0, REG_SZ, (const BYTE *)szDll, _tcslen(szDll)*sizeof(TCHAR)); DWORD dwValue = 1; RegSetValueEx(hKey, L"UserCanCreate", 0, REG_DWORD, (const BYTE *)&dwValue, sizeof(DWORD)); dwValue = 0; RegSetValueEx(hKey, L"Port", 0, REG_DWORD, (const BYTE *)&dwValue, sizeof(DWORD));     RegCloseKey(hKey);    }    lResult = RegCreateKeyEx(HKEY_CURRENT_USER, L"System\State\Messages\VVM", 0, NULL, 0, 0, NULL, &hKey, &dwDisp);    if (lResult == ERROR_SUCCESS)   {   TCHAR szName[] = L"VVM"; //RegSetValueEx(hKey, L"Account Name", 0, REG_SZ, (const BYTE *)kszVVMStoreName, _tcslen(kszVVMStoreName)*sizeof(TCHAR)); RegSetValueEx(hKey, L"Account Name", 0, REG_SZ, (const BYTE *)szName, _tcslen(szName)*sizeof(TCHAR)); RegCloseKey(hKey);   } } Message Store Creation:

HRESULT CRuleClient::CreateMsgStore(LPCWSTR pszDisplayName, IMsgStore ** ppMsgStore) { HRESULT hr=E_FAIL; ICEMAPISession*  pSession = NULL; IMAPITable* pTable = NULL; IMsgStore* pStore = NULL; LPSRowSet FAR pRows = NULL; DEBUG_INS->Print("CRuleClient::CreateMsgStoren"); // Initialize MAPI hr = MAPIInitialize(NULL); CHR(hr); // Obtain MAPI session hr = MAPILogonEx( 0,    // Handle to parent window NULL, // Profile name NULL,   // Password MAPI_NEW_SESSION |MAPI_EXTENDED |MAPI_LOGON_UI, // Logon flags (LPMAPISESSION*)&pSession);  // Resulting MAPI session CHR(hr); ppMsgStore = NULL; hr = pSession->CreateMsgStore(/pszDisplayName/_T("VVM"), ppMsgStore); CHR(hr); hr = pSession->GetMsgStoresTable(0, &pTable); CHR(hr); hr = pTable->QueryRows(1, 0, &pRows); CHR(hr); hr = pSession->OpenMsgStore( 0, pRows->aRow[0].lpProps[0].Value.bin.cb, (ENTRYID *)pRows->aRow[0].lpProps[0].Value.bin.lpb, NULL, 0, &pStore); CHR(hr); Error: DEBUG_INS->Print("CRuleClient::CreateMsgStore ERROR!n"); Exit: if(pTable) pTable->Release(); if(pRows) FreeProws(pRows); if(ppMsgStore && *ppMsgStore) (*ppMsgStore)->Release(); pSession->Logoff(0, 0, 0); pSession->Release(); pSession = NULL; ::MAPIUninitialize();     return hr; }

  • Anonymous
    June 02, 2008
    Hi Selva, you can turn off the notification using PR_CE_NO_NOTIFICATION. Set this in ulPropTag field of 'SPropValue' and invoke SetProps. You would see the message notification not being displayed.

  • Anonymous
    June 02, 2008
    Jay, Could you please help me with setting status of the outgoing SMS. I could dig out 'PR_MSG_STATUS' field as ulPropTag, but could not find an appropriate one for 'Value.ul' Appreciate your help. Thanks!

  • Anonymous
    June 21, 2008
    How do we delete an account? I created email account that appears as Other (POP/IMAP). How can I delete it through API (C/C++) or .NET? I can see that it can be deleted from messaging application but couldn't find any API.

  • Anonymous
    July 02, 2008
    Hi :) We have problem with retrieving MMS messages. We are able to get subject, phone nr, date. The main problem is we aren't able to get body like photo file. In our work we use a Palmtop(QTEK S100) with operating system Windows Mobile 2003 SE and library CEMAPI in C++. I know I can use IMessage... but i don`t know how to get a pointer to IMessage:( http://msdn.microsoft.com/en-us/library/bb446198.aspx Can Any one help please?

  • Anonymous
    July 21, 2008
    The comment has been removed

  • Anonymous
    August 25, 2008
    I use: SPropValue rgProps[4] = {0}; int rgValues = 0; rgProps[rgValues].ulPropTag = PR_CE_HIDE_FROM_TODAY_PAGE; rgProps[rgValues].Value.b = TRUE; rgValues++; // prevent default notification rgProps[rgValues].ulPropTag = PR_CE_NO_NOTIFICATION; rgProps[rgValues].Value.b = TRUE; rgValues++; pMsg->SetProps(rgValues, rgProps, NULL); and the default notification sounds still is playing... note: when I add to the above: rgProps[rgValues].ulPropTag = PR_MESSAGE_FLAGS; rgProps[rgValues].Value.ul  = MSGFLAG_READ; the sound does not play. of course (?)

  • Anonymous
    August 25, 2008
    Of course, I undestand, that PR_CE_NO_NOTIFICATION is for pop-up (bubble) notification. but how to prevent from default sound notification too? I think about MRC_HANDLED_DONTCONTINUE but when someone uses also another mapi-rule application, this state breaks that 3rd parts function too, isn't it?

  • Anonymous
    August 26, 2008
    Hi, I want to create a new message store and see it displayed alongside the existing message stores in the Messaging application. I call CreateMsgStore and it returns OK, and I can then enumerate using GetMsgStoresTable and I see my new store has been created. I don't however see my message store displayed in the messaging application. Is there something else I need to do?  Are there registry keys I also need to set?

  • Anonymous
    September 05, 2008
    Hi, I am using MAPI to retrieve contact information from outlook. I am using outlook 2007. I am able to get most of the contact fields, But i am not able to get Contact Image data. Do you have any idea about this? i really need help on it.

  • Anonymous
    October 08, 2008
    Hi All! As I understand, nobody finished the task - sending MMS. Is working code exist? Thanks.

  • Anonymous
    December 05, 2008
    Hi Jay/all, If I tap into mapi (cemapi.dll) from managed code (C#) using com interop is this supported and/or wise.  I note that the desktop mapi libraries are not supported by MS when used with managed code.  If it is 'ok' to access cemapi.dll from managed C# then does anyone have any examples of how to call, say, IMAPITable.SetColumns (I've got code working as far as IMAPISession.GetMsgStoresTable but I'm stuck trying to define my prop array in C# for the SetColumns call).  Any help would be hugely appreciated - thanks very much!

  • Anonymous
    February 02, 2009
    Can this MAPI stuff be done in visual basic? if so can you post the example code

  • Anonymous
    March 15, 2009
    I love to see some why to send email from visual basic too..

  • Anonymous
    March 15, 2009
    Hi Can you plz help me out in sending an MMS from windows mobile using c#.