1

My goal, the user wants to send a new email, after filling in (.TO, .CC, .Body etc) and clicking on the send button will display a custome Form where the sending options are. One option is to send the email as the user created it (normal send button function). Is there any idea how to assign ItemSend function to button in custom form ?

ThisAddIn.cs -> open custom Form

public partial class ThisAddIn
{
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);

    }

Application_ItemSend

   private void Application_ItemSend(object Item, ref bool Cancel)
   {
        if (Item is Outlook.MailItem)
        {
            Form1 f = new Form1();
            f.Show();
        }

        Cancel = true;
    }

ChooseFormSend.cs -> custom sending button,

    public void btn_standard_Click(object sender, System.EventArgs e)
    {
         //mail.Send() -> send email which user whant to send        

    }

UPDATE (all aswers to gether, to make this work)

ThisAddIn.cs

public partial class ThisAddIn
{
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);

    private bool ProcessEmail(Outlook.MailItem mailItem, MailSendType SendType)
    {
        switch (SendType)
        {
            case MailSendType.Normal:
                return false;

            case MailSendType.WithAdverts:
                //mailItem.BCC += "ad@server.xyz";
                mailItem.HTMLBody += @"<b>Some bold text at the end :)</b>";
                mailItem.HTMLBody += @"1233";
                return false; // send the mail

            case MailSendType.WithCoupon:
                mailItem.CC += "coupon@server.xyz";
                mailItem.HTMLBody += @"";
                return false; // send the mail

            // by default don't send the mail
            default:
                return true;
        }
    }

    private void Application_ItemSend(object Item, ref bool Cancel)
    {
        if (Item is MailItem) // ensures Item is a mail item
        {
            using (Form1 form_ChooseForm = new Form1())
            {
                DialogResult dr = form_ChooseForm.ShowDialog();
                if (dr == DialogResult.OK) // shows the form as a dialog
                {
                    Cancel = ProcessEmail((MailItem)Item, form_ChooseForm.SendType);
                    // MessageBox.Show("The OK button on the form was clicked.");                 
                }
                else
                {
                    // MessageBox.Show("Cancel process");
                    Cancel = true;
                }
            }   
        }
    }
}

ChooseFormSend.cs

using Microsoft.Office.Core;
using Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Tools.Outlook;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Mail;
using System.Runtime.InteropServices;

namespace OutlookControll

{
    public enum MailSendType
    {
        NoSend,
        Normal,
        WithAdverts,
        WithCoupon
    }
    public partial class Form1 : Form
    {
    public Form1()
    {
        InitializeComponent();
    }

    public MailSendType SendType = MailSendType.NoSend;

    private void Btn_ShowSecondForm_Click(object sender, EventArgs e)
    {
        AddItemsForm f2 = new AddItemsForm();
        f2.ShowDialog();
        this.Hide();
    }

    private void Btn_cancel_Click(object sender, EventArgs e)
    {
        Button Btn_cancel_Click = new Button();
        Btn_cancel_Click.DialogResult = DialogResult.Cancel;
        this.Hide();
    }

    public void Btn_standard_Click(object sender, EventArgs e)
    {
        Button Btn_standard_Click = new Button();
        Btn_standard_Click.DialogResult = DialogResult.OK;
        Controls.Add(Btn_standard_Click);
        SendType = MailSendType.Normal;
        this.Hide();
    }

}

Btn_standard_Click.DialogResult = DialogResult.OK can be setup in Properties -> Behavior -> DialogResult -> OK, Cancel, Abort, etc.

Novice
  • 363
  • 10
  • 32

1 Answers1

3

There are 3 potential scenarios I can consider:

  1. Press send > Form pops up > Select option on Form > Modify email contents > Send email
  2. Press send > Form pops up > Select option on Form > Create and send new email (sending 1 or more new emails)(discard old email) > Send email
  3. Press send > Form pops up > Select option on Form > Create and send new email (sending 1 or more new emails)(send old email) > Send email

Note that once modifying the email contents can mean modifying everything. Change the sender change the subject etc. So if you want to create a single new email and discard the old one option 1 still works to just manipulate the original email completely.

The Dialog to allow the user to select the relevant options.

Note: When placing the form buttons ensure to set the DialogResult option under Behavior in the properties inspector. This allows for a DialogResult:OK to be returned once clicking one of the buttons automatically closing and returning from the dialog.

public enum MailSendType
{
    NoSend,
    Normal,
    WithAdverts,
    WithCoupon
}

public partial class SendItemForm : Form
{
    public SendItemForm()
    {
        InitializeComponent();
    }

    public MailSendType SendType = MailSendType.NoSend;

    private void button1_Click(object sender, EventArgs e)
    {
        SendType = MailSendType.Normal;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        SendType = MailSendType.WithAdverts;
    }
}

Option 1: Only modifying the contents of the email

Note the show f.ShowDialog() instead of f.Show() this stops the current thread from continuing the send operation and waits for the user to select a button on the form. The f.SendType from the dialog is set and used to indicated which option the user selected. Using ProcessEmail the email can me manipulated and return false results in the manipulated email being send as the false propagates down to parent functions Cancel = false (Don't cancel the send).

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        // create a global event listener for sending items
        Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
    }

    // this function is used to modify the mail object before sending it (More variables could be added to extend the functionality)
    private bool ProcessEmail(Outlook.MailItem mailItem, MailSendType sendType)
    {
        switch (sendType)
        {
            case MailSendType.Normal:
                return false; // send the mail as is don't mainpulate the mailItem variable

            case MailSendType.WithAdverts:
                mailItem.BCC += "ad@server.xyz";
                mailItem.HTMLBody += @"<b>Some bold text at the end :)</b>";
                mailItem.HTMLBody += @"</img src='https://server.xyz/ad1.png'>";
                return false; // send the mail

            case MailSendType.WithCoupon:
                mailItem.CC += "coupon@server.xyz";
                mailItem.HTMLBody += @"</img src='https://server.xyz/coupon1.png'>";
                return false; // send the mail

            // by default don't send the mail
            default:
                return true;
        }
    }

    private void Application_ItemSend(object Item, ref bool Cancel)
    {
        if (Item is Outlook.MailItem) // ensures Item is a mail item
        {
            using (SendItemForm f = new SendItemForm()) // creates the form
                if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK) // shows the form as a dialog
                    //if statement ensures the process will only proceed if an OK is returned 
                    //(The form has a cancel button or it could crash or anything else)
                    Cancel = ProcessEmail((Outlook.MailItem)Item, f.SendType); // process the email with the SendType
        }
    }

Option 2/3 Sending new emails

This method highlights how to send new emails in outlook. Note: Tested sending email with MailItem.Send() and it does not call Application_ItemSend again

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
    }

    private void SendNewEmail(string to, string greeting, MailSendType sendType)
    {
        Outlook.MailItem newMailItem = Application.CreateItem(Outlook.OlItemType.olMailItem);
        newMailItem.To = to;
        newMailItem.SendUsingAccount = Application.Session.Accounts[1]; // Optional can leave blank to send from default account (Array starts at 1)
        newMailItem.Subject = "New Mail";
        newMailItem.Body = $"{greeting} {newMailItem.To}\nExample Body from {sendType.ToString()}";

        // Part of Original answer but it's not relevant. However I will leave it in the event that it is of use to someone
        //((Outlook.ItemEvents_10_Event)newMailItem).Send += (ref bool Cancel) => { /*do nothing*/ };

        newMailItem.Send(); // send the mail
    }

    private void Application_ItemSend(object Item, ref bool Cancel)
    {
        if (Item is Outlook.MailItem) // ensures Item is a mail item
        {
            using (SendItemForm f = new SendItemForm()) // creates the form
                if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK) // shows the form as a dialog
                {
                    //if statement ensures the process will only proceed if an OK is returned 
                    //(The form has a cancel button or it could crash or anything else)

                    // send 3 mails
                    SendNewEmail("admin1@server.xyz", "Hi", f.SendType);
                    SendNewEmail("admin2@server.xyz", "Hello", MailSendType.Normal);
                    SendNewEmail("admin3@server.xyz", "Yo", f.SendType);

                    // either send or don't send the orginal one
                    // by default Cancel is set to false (So by default the message will send)

                    // send the 3 mails and send the original one typed up by the user
                    //Cancel = false;

                    // send the 3 mails and do not send the original one currently typed up by the user
                   // Cancel = true;
                }

        }
    }

Between these 2 examples and the f.ShowDialog() setup you should be able to find the solution you seek. You can also mix and match by modifying the original email and sending additional one.

Kwiksilver
  • 775
  • 4
  • 13
  • what im doing wrong, i follow your option 1, and email will be send only when i click cancel botton, or close form with cross button in right up corner in form. – Novice Sep 22 '20 at 08:19
  • In the method `void Application_ItemSend(object Item, ref bool Cancel)` the `Cancel` variable can be set. `Cancel = true; // Message will not send` `Cancel = false; // (Default) Message will send` `ShowDialog()` will return `DialogResult.OK` or `DialogResult.Cancel`. From this you can set `Cancel` See the [Microsoft](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.form.dialogresult) example and see this [StackOverflow post](https://stackoverflow.com/questions/16846573/using-dialogresult-correctly) for a bit more detail on how the a modal dialog works. – Kwiksilver Sep 23 '20 at 16:22
  • Updated question about all information collected. Let's make it a little more complicated, what if I have a second ````Form```` ? To send another type of email? ````Application_ItemSend```` controls the first form. One of the buttons of the first form opens the second form where the user is prompted to enter ````Imput```` and the email is sent to the same recipient as in the case of the first form – Novice Sep 30 '20 at 14:32
  • The new updated question while valid is not entirely related to the first question. You are better off asking a new question. Large problems can be broken down into smaller targeted ones. Focused question are better suited to SO. Searching "multiform c# application" turns up many results. [This](https://stackoverflow.com/questions/9462592/best-practices-for-multi-form-applications-to-show-and-hide-forms) SO link shows some slightly more complex approaches to handling a multiform setup. I would also suggest using a wizard style approach (click next and back rather opening new forms) – Kwiksilver Oct 02 '20 at 11:03