How to replicate Outlook Send functionality in VSTO using C#

  • Thread starter Thread starter Aravind
  • Start date Start date
A

Aravind

I posted in the VSTO forums and was advised to post here as people with
Outlook expertise visit this forum more frequently. My environment is:

Visual Studio 2005
Outlook 2003
Windows XP SP2.

I am creating an add-in for Outlook that will pretty much replicate the Send
functionality (including ResolveNames and Check Spelling) and adds some
custom functionality (to file the sent mail in a different folder than the
sent folder or to print the sent email immediately etc.). Initially I had
thought to do this by registering for the send event (ie.
Microsoft.Office.Interop.Outlook.ApplicationEvents_11_ItemSendEventHandler)
but the requirement is that the add-in must have its own button that starts
the sending process and should not interfere with the normal "Send" that
outlook provides. After a little bit of fiddling I found the way to execute
the Resolve Names and Spell check but they don't quite work the same as when
the user clicks the "Send" button (i.e. they are not seamless). I have not
been successful in trying to "Execute" the send button using the same logic.
The below code (for ex.) executes the Spell Check functionality.


MSO.CommandBar toolsmenubar = null;

toolsmenubar =
Globals.ThisApplication.ActiveInspector().CommandBars.ActiveMenuBar;


MSO.CommandBarButton spellcheckbutton = null;

if (toolsmenubar != null)
{
// try to find button
spellcheckbutton =
(MSO.CommandBarButton)toolsmenubar.FindControl(myMissing,
IDSPELLCHECKBUTTON.ToString(), myMissing, myMissing, true);
}

if (spellcheckbutton != null)
{
if (spellcheckbutton.Enabled.Equals(true))
{
try
{
spellcheckbutton.Execute();
}
catch (System.Exception ex)
{
MessageBox.Show("An error occured when trying to send this
message." + "\n" + "Error: " + ex.Message,
"Outlook Add-in", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}


IDSPELLCHECKBUTTON is defined as constant 2

IDSENDBUTTON is defined as constant 2617 (I also tried 3037 for File->Send)

In the above code block if I replace IDSPELLCHECKBUTTON with IDSENDBUTTON I
get an Exception and the send does not work.

Any help in getting the Send to work using the execute will be very
appreciated. Obviously I don't want to use mailItem.Send because that way
it doesn't do the resolve names and spell check functions.


Thanks,

Aravind
 
buttonSend.Execute is blocked by the security. If you want to resolve the
recipients you can do so in code using the Recipient.Resolve() method or by
using Recipients.ResolveAll(). Then you could call item.Send().

The Outlook object model doesn't expose the resolution dialog until Outlook
2007's NameSpace.GetSelectNamesDialog() method.
 
Thanks Ken for your reply. I have indeed used Receipient.ResolveAll to
resolve the names. My problem was with the Spell Check. Do you know of any
way to invoke that the same way that the "Send" invokes it? I am able to
invoke the Spell Check using the Execute method but I can't find a way of
checking if the user clicked the "Cancel" halfway through the spell check or
for suppressing the "Spell Check is Complete". message.


Thanks,

Aravind
 
No, there's no way I know of to replicate that functionality from a code
call.
 
Thanks. Until I find a better solution, I got around by doing:

System.Windows.Forms.SendKeys.Send("%S");


Aravind
 
Hi Aravind and Ken,

How did you manage to "file the sent mail in a different folder"? I have put
a handler on the Sent Folder ItemAdd event so that when Items are added to it
the handler is called. I wanted to then move the mail to the required folder.

using Outlook = Microsoft.Office.Interop.Outlook;

defaultFolder =
this.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
defaultFolder.Items.ItemAdd += new
Microsoft.Office.Interop.Outlook.ItemsEvents_ItemAddEventHandler(SentItems_ItemAdd);

What I find is that when I send a mail composed in Outlook the handler is
called. correctly. However if I send a mail that I created in the code of my
plugin my handler is not called.

Outlook.MailItem mail = outlookApp.CreateItem(Outlook.OlItemType.olMailItem)
as Outlook.MailItem;
....// Fill in Message details eg. Subject, body etc
((Outlook._MailItem)mail).Send();

The mail is still sent and added to the Sent Folder but the handler is not
invoked. Am I doing something wrong here?

Please help.
Vimesh
 
Perhaps your handler is going out of scope? Is the object used
(defaultFolder) declared at class level and not in a procedure? If it's a
local object variable it will go out of scope when the procedure ends and
end up garbage collected.
 
Vimesh,

I face a similar problem and haven't found a workaround. When I create a
new email (i.e., use "New" then the sentitems itemadd event fires. But if I
reply to an existing email or forward an email, it does not.

Regarding your other question, I am using "myMailItem.SaveSentMessageFolder
= folder;" before the call to mailitem.send to have outlook automatically
move the current item into the appropriate folder.

Ken,

I have the variable declared at the class level, but the event doesn't
always fire. Like I said above, it always fires if the user is typing up a
new email but does not if it is a reply or forward.


Aravind
 
I've never seen that here at all. No matter if it's a reply, replyall,
forward or new message if it goes to Sent Items after sending then I get
ItemAdd on the Items collection of that folder. That's assuming that 15 or
fewer items are added at once, otherwise the MAPI limitation on those events
comes into play and the event does not fire.
 
Ken and Aravind,

I have checked the scope of "defaultFolder" and it is a member of the
partial class "ThisApplication" (The auto generated code for a plugin using
VSTO) and so is the "Items_ItemAdd" event handler so they should not go out
of scope, as far as I can see.

I tried Aravind's suggestion of using the "SaveSentMessageFolder" property
and that works in saving a copy of the mail to a specified folder, which is
what I was trying to achive by getting the mail from the sent folder and
moving it to the custom folder.

Thank you for the help.
 
Back
Top