views:

651

answers:

4

Hello

I am trying to use SimpleMAPI to display a 'write message' dialogue with an attachment on Vista SP1 with either Windows Mail or Thunderbird in a C++ app (Borland C++ Builder 2006). I should be able to use MAPISendMail to do this.

I don't fill in a recipient address as I expect the user to do that when the mail client displays a 'write message' dialog. I also don't fill in an originator address as I expect the mail client to use the default. I have tried hardcoding them to see if thats the problem and it is not.

My code looks like this:

HINSTANCE hMAPI;
LPMAPISENDMAIL pSendMail;
MapiMessage message;
MapiFileDesc file;

ZeroMemory( &message, sizeof( MapiMessage ) );
ZeroMemory( &file, sizeof( MapiFileDesc ) );

hMAPI = LoadLibraryA( "MAPI32.DLL" );

pSendMail = (LPMAPISENDMAIL)GetProcAddress( hMAPI, "MAPISendMail" );

// setup the attachment...
file.nPosition     = -1;
file.lpszPathName  = "C:\\my_attachment.dat";

// set up the message...
message.lpszSubject     = "My Subject";
message.lpszNoteText    = "My Message...";
message.lpszMessageType = "";
message.nRecipCount     = 0;
message.lpRecips        = NULL; // we don't know the recipient address(s)
message.nFileCount      = 1;
message.lpFiles         = &file;
message.lpOriginator    = NULL; // we don't know the users from address

dwResult = pSendMail( lhSessionNull, (DWORD)Application->Handle, &message, MAPI_LOGON_UI | MAPI_DIALOG, 0 );
if( dwResult == SUCCESS_SUCCESS )
{ 
  // ...yay! :)
}
else
{
  // ...we always fail here with: MAPI_E_FAILURE
}

It always fails with error code 2 (MAPI_E_FAILURE). What am I doing wrong?

Many thanks in advance.

A: 

You have to first logon to the MAPI session

LHANDLE hMapiSession;
status = lpMapiLogon(NULL, NULL, NULL, MAPI_NEW_SESSION | MAPI_LOGON_UI, 0, &hMapiSession);

then, you can call SendMail(). And after that, you have to logoff again:

lpMapiLogoff(hMapiSession, NULL, 0, 0);
Stefan
Stefan: Thanks but afraid that doesn't work. MAPILogon also returns an error code of 2. And I thought you don't need to call MAPILogon if you pass MAPI_LOGON_UI to MAPISendMail.
QAZ
There are several different MAPI implementations. You don't need to call MAPILogon for the Outlook MAPI. But you have to do it with the Thunderbird MAPI (at least for version 1, never tested it with later versions). Othere implementation might require this too.
Stefan
A: 

message.lpRecips = NULL; // we don't know the recipient address(s)

Try assinging lpRecips and set it's lpszAddress to "SMTP:"

andremo
A: 

Using similar in Delphi and discovered that it does not work from inside a thread. (Delphi TThread component) I used the exact same code and call from within the thread always failed, even though I used synchronize

Paul Mc