VSTO从Outlook中的自定义窗体按钮发送电子邮件

问题描述

我的目标是,用户要发送一封新电子邮件,请先填写(.TO.CC.Body等),然后单击“发送”按钮,将显示一个自定义{{ 1}}在哪里发送选项。一种选择是在用户创建电子邮件时发送它(正常的Form按钮功能)。 有什么主意如何将send功能分配给自定义格式的按钮?

ItemSend->打开自定义表单

ThisAddIn.cs

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

更新(为了使这项工作生效,请稍等片刻

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

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 += "[email protected]"; mailItem.HTMLBody += @"<b>Some bold text at the end :)</b>"; mailItem.HTMLBody += @"1233"; return false; // send the mail case MailSendType.WithCoupon: mailItem.CC += "[email protected]"; 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-> Properties-> Behavior->确定,取消,中止等等中进行设置。

解决方法

我可以考虑3种潜在情况:

  1. 按发送>弹出表单>在表单上选择选项> 修改电子邮件内容>发送电子邮件
  2. 按发送>弹出表单>在表单上选择选项> 创建和发送新电子邮件(发送1个或更多新电子邮件)(丢弃旧电子邮件)>发送电子邮件
  3. 按发送>弹出表单>在表单上选择选项> 创建和发送新电子邮件(发送1个或更多新电子邮件)(发送旧电子邮件)>发送电子邮件

请注意,一旦修改了电子邮件内容,可能意味着要修改所有内容。更改发件人,更改主题等。因此,如果您要创建一封新电子邮件并丢弃旧邮件,则选项1仍然可以完全操纵原始电子邮件。

允许用户选择相关选项的对话框。

注意:放置表单按钮时,请确保在属性检查器的“行为”下设置DialogResult选项。一旦点击其中一个自动关闭并从对话框返回的按钮,就可以返回DialogResult:OK

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;
    }
}

选项1:仅修改电子邮件的内容

请注意显示f.ShowDialog()而不是f.Show(),这将阻止当前线程继续发送操作,并等待用户选择表单上的按钮。对话框中的f.SendType被设置并用于指示用户选择了哪个选项。使用ProcessEmail可以操纵电子邮件,而return false导致操纵的电子邮件在false向下传播到父功能Cancel = false时发送(不要取消发送)。

    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 += "[email protected]";
                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 += "[email protected]";
                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
        }
    }

选项2/3发送新电子邮件

此方法突出显示了如何在Outlook中发送新电子邮件。注意:已测试使用MailItem.Send()发送电子邮件,并且不会再次调用Application_ItemSend

    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("[email protected]","Hi",f.SendType);
                    SendNewEmail("[email protected]","Hello",MailSendType.Normal);
                    SendNewEmail("[email protected]","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;
                }

        }
    }

在这两个示例与f.ShowDialog()设置之间,您应该能够找到所需的解决方案。您还可以通过修改原始电子邮件并发送其他电子邮件来混合搭配。