Trapping an external mapi send (pre ItemSend)

Add-in Express™ Support Service
That's what is more important than anything else

Trapping an external mapi send (pre ItemSend)
 
edbored




Posts: 8
Joined: 2010-01-08
I'm a bit of a newbie with the adx libs...

I've a situation where a custom application will send an email message via MAPI mail call, or Outlook ComObj automation.

This custom application may send from various modules. I need to pre-process the mail prior to end-user seeing it in Outlook 'new mail' dialog screen. That is, the subject may contain tags indicating which module sent the message - I want to parse the tags, replacing it with a custom subject depending on tag value.

So, are there any events that will allow me to parse the _MailItem before the end-user sees anything?


Thanks.

EdB
Posted 08 Jan, 2010 02:19:18 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
Hello EdB,

If only the application sends e-mails via Outlook, you can develop an add-in that handles, say, the ItemSend event of Outlook.Application. In that event, you can modify the e-mail as required.


Andrei Smolin
Add-in Express Team Leader
Posted 08 Jan, 2010 11:22:40 Top
edbored




Posts: 8
Joined: 2010-01-08
Hi Andrei.

The ItemSend event is 'too late' (doesn't trigger until user hits 'send').

Also, if the message is composed and sent completely within Outlook, I don't even touch it.

I'm trying to find a way of having email sent from non-outlook applications ("NOA") trapped in Outlook before the end-user sees the message in the 'compose new mail' dialog.

Is there some way to detect that the 'new message' form in Outlook has triggered? Perhaps there's some way to grab the _MailItem information before the user sees the form - if I find the tag value in the subject, I can parse the message before the end user sees the information.

So, something like:

-NOA (module 1) performs MAPI send mail. (subject='MyMOD1')

-Outlook handles the external MAPI call, creates 'new mail dialog'

-Add-in handles 'new mail form OnCre ate' event
- parse subject,
if MyMOD1 - change subject, manipulate body
if MyMOD2 - change subject, manipulate body, add attachment
if ...

- 'new mail form' appears to end user with changes
- User changes body as needed. Clicks Send
- ItemSend event handles some final processing.

Is there some other mechanism I could use to perform the above? I'm thinking custom x-header added by 'NOA' - but again, I may need to process the message *before* the end-user sees it - and certainly before the user clicks 'send'.


Thanks again.
Posted 08 Jan, 2010 12:23:22 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
Hi EdB,

before the end-user sees the message in the 'compose new mail' dialog


"Compose New Mail"?

If you need to modify the e-mail on the receiving side, not on the sending one, then you can try using the Open event. This requires handling ExplorerSelectionChange event and connecting to events of the selected item(s). Note that the user can select one e-mail, right click another one and choose Open. That scenario cannot be handled in Outlook 2000-2003. In Outlook 2007, you can handle the ItemContextMenuDisplay event, a parameter of which allows accessing the item(s) being opened via the context menu.

Another way is to modify the e-mail as soon as it is received. But the universal way to handle all scenarios of receiving e-mails requires to scan all folders periodically. In Outlook 2007, you can parse rules and identify the folders to be scanned.


Andrei Smolin
Add-in Express Team Leader
Posted 08 Jan, 2010 17:20:07 Top
edbored




Posts: 8
Joined: 2010-01-08

"Compose New Mail"?


Yes, well, my first line of first post was: "I'm a bit of a newbie with the adx libs... " <g>


Having realized I was looking for 'Inspectors' I found enough examples to build the following:


procedure TAddInModule.adxOutlookAppEvents1NewInspector(ASender: TObject;
  const Inspector: _Inspector);
var
  IMail : _MailItem;
  s     : string;
begin
  OutputDebugString('NewInspector');
  IMail:=nil;
  if Assigned(Inspector) then begin
    OutputDebugString('Inspector Assigned');
    if Assigned(Inspector.CurrentItem) then begin
      OutputDebugString('CurrentItem Assigned');
      Inspector.CurrentItem.QueryInterface(IID__MailItem, IMail);
      try
        if (IMail<>nil) then begin
          OutputDebugString('IMail Assigned');
          if (IMail.EntryID = '') then   begin
            s:='To: '+IMail.To_;
            OutputDebugString(PAnsiChar(s));
            s:='Subject: '+IMail.Subject;
            OutputDebugString(PAnsiChar(s));
          end;
        end;
      finally
       IMail:=nil;
      end;
    end;
  end;
end;


Unfortuantely, this is still causing problems:

OnNewInspector is not fired when I send a mail message from a D7 application (using TMapiMessage). The Inspector pops-up, with my message ready to send, but the event isn't fired (neither is 'OnInspectorActivate').

Thanks.

Cheers,
EdB
Posted 18 Jan, 2010 16:36:09 Top
edbored




Posts: 8
Joined: 2010-01-08
edbored writes:
Unfortuantely, this is still causing problems:

OnNewInspector is not fired when I send a mail message from a D7 application (using TMapiMessage). The Inspector pops-up, with my message ready to send, but the event isn't fired (neither is 'OnInspectorActivate').


Just found a lot of relate messages about this when sending from Windows Explorer context menu: Outlook doesn't trigger the events.

I've found, however, if I don't send mail using TMapiMessage in my external application, but use the code below, then Outlook triggers as expected.


Uses 
  ...
  ComObj,
  ---;

procedure TForm1.btnOleSendClick(Sender: TObject);
 const
  olMailItem = 0;
var
  Outlook, MailItem: OLEVariant;
begin
  try
    Outlook := GetActiveOleObject('Outlook.Application');
  except
    Outlook := CreateOleObject('Outlook.Application');
  end;

  MailItem := Outlook.CreateItem(olMailItem);
  MailItem.Recipients.Add(editTo.Text);
  MailItem.Subject := editSubject.Text;
  MailItem.Body := memoBody.Text;
//  MailItem.Attachments.Add(aFileNameHere);
  MailItem.Display;
  Outlook := Unassigned;
end;


Hope this helps someone else!

Cheers,
EdB
Posted 18 Jan, 2010 16:57:24 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
Hi Ed,

Thank you. This works because your code sends e-mails via the Outlook object model.


Andrei Smolin
Add-in Express Team Leader
Posted 19 Jan, 2010 05:36:53 Top