如何将Outlook-Mail拖放到richTextBox中 [英] How to Drag&Drop Outlook-Mail into richTextBox

查看:153
本文介绍了如何将Outlook-Mail拖放到richTextBox中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的WinForms-Application有一个问题;我想将Outlook邮件拖放到RichTextBox中。我发现了许多关于拖放功能的文章,但他们都将Mailtext插入rTB(参见:。)



代码

  private void Form 1DragDrop(object sender,DragEventArgs e)
{
Startup();
//Microsoft.Office.Interop.Outlook.ApplicationClass oApp =
// new Microsoft.Office.Interop.Outlook.ApplicationClass();
Microsoft.Office.Interop.Outlook.Explorer oExplorer = _Outlook.ActiveExplorer();
Microsoft.Office.Interop.Outlook.Selection oSelection = oExplorer.Selection;

foreach(oSelection中的对象项)
{
Microsoft.Office.Interop.Outlook.MailItem mi =(Microsoft.Office.Interop.Outlook.MailItem)项;

rTB_test.Text = mi.Body.ToString();

string mailName =Mail\\\
+(mailList.Count + 1);
//在底部加载足够空间的图像以添加一些文本:
Image img = Image.FromFile(Imagepath);
//现在我们添加文本:
int width = img.Width;
使用(Graphics G = Graphics.FromImage(img))
using(Font font = new Font(Arial,7f))
{
SizeF s = G.MeasureString (mailName,font,width);
G.DrawString(mailName,font,Brushes.Black,
(width-s.Width)/ 2,img.Height - s.Height - 1);

}
//添加图像很容易只有我们使用剪贴板。
Clipboard.SetImage(img);
//现在插入图像
rTB_test.Paste();
//现在我们可以得到一个哈希码作为唯一的密钥..
// ..选择我们刚刚插入的图像:
rTB_test.SelectionStart = rTB_test.TextLength - 1;
rTB_test.SelectionLength = 1;
//最后,我们需要使用其密钥存储邮件本身:
mailList.Add(rTB_test.SelectedRtf.GetHashCode(),mi);
// cleanup:取消选择并将游标设置为结束:
rTB_test.SelectionStart = rTB_test.TextLength;
rTB_test.SelectionLength = 0;
}
Microsoft.Office.Interop.Outlook.Application _Outlook = null;

字典< int,Microsoft.Office.Interop.Outlook.MailItem> mailList =
new Dictionary< int,Microsoft.Office.Interop.Outlook.MailItem>();

private void rTB_test_DoubleClick(object sender,EventArgs e)
{
var ss = rTB_test.SelectionStart;
var sl = rTB_test.SelectionLength;
int hash = rTB_test.SelectedRtf.GetHashCode();
//几个检查:
if(sl == 1&&&& mailList.Keys.Contains(hash))
{
Microsoft.Office.Interop.Outlook。 MailItem mi = mailList [hash];
//与msgItem一起做东西
// ..
}
}

void lbl_MouseDoubleClick(object sender,MouseEventArgs e)
{
Microsoft.Office.Interop.Outlook.MailItem mi =
(Microsoft.Office.Interop.Outlook.MailItem)((Label)sender).Tag;
//处理双击邮件的代码
}

void Startup()
{
_Outlook = new Microsoft.Office.Interop。 Outlook.Application();
}

private void Form1_DragEnter(object sender,DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}

用户双击图片后,应在Outlookexplorer中打开邮件。



更新



如果我使用代码从TaW的答案中给出以下输出:





双击图标后,邮件不会被打开...所以答案中的代码只是一个图标创建。
谢谢高级!

解决方案

这是我在评论中的意思:

  private void Form1DragDrop(object sender,DragEventArgs e)
{
Startup();
Microsoft.Office.Interop.Outlook.ApplicationClass oApp =
new Microsoft.Office.Interop.Outlook.ApplicationClass();
Microsoft.Office.Interop.Outlook.Explorer oExplorer = _Outlook.ActiveExplorer();
Microsoft.Office.Interop.Outlook.Selection oSelection = Explorer.Selection;

foreach(oSelection中的对象项)
{
Microsoft.Office.Interop.Outlook.MailItem mi =
(Microsoft.Office.Interop.Outlook.MailItem)项目;
// rTB_test.Text = mi.Body.ToString();
标签lbl = new Label();
lbl.AutoSize = false;
lbl.Size = new Size(80,50); //< - 你的选择!
lbl.Text = someText; //< - 你的选择!
lbl.TextAlign = ContentAlignment.BottomCenter;
lbl.Image = someImage; //< - 你的选择!
lbl.ImageAlign = ContentAlignment.TopCenter;
int count = rTB_test.Controls.Count;
int itemsPerRow = rTB_test.Width / 80;
lbl.Location = new Point((count%itemsPerRow)* 80,
count / itemsPerRow * 50);
lbl.Tag = mi; //存储数据对象
lbl.MouseDoubleClick + = lbl_MouseDoubleClick;
lbl.Parent = rTB_test; //添加到RTF的控件
}
}

void lbl_MouseDoubleClick(object sender,MouseEventArgs e)
{
Microsoft.Office.Interop.Outlook .MailItem mi =
(Microsoft.Office.Interop.Outlook.MailItem)((Label)sender).Tag;
//处理双击邮件的代码
}

这些标签将位于RTB中的任何文本之上,而不会干扰它。如果你想要的话,你可以修改位置的代码,以便以其他方式将它们移出或者标注样式。



更新



最后一句话后,问题得到了很清楚:应用程序的其他部分已经在RTB中添加了邮件图标,我们将添加更多的相同的'..



添加图像最好通过剪贴板完成;这里是代码可以做到这一点:

  //创建一些测试文本,也许从邮件头提取它.. 
string mailName =Mail\\\
+(mailList.Count + 1);
//在底部加载足够空间的图像以添加一些文本:
Image img = Image.FromFile(yourMailImageFile);
//通过在一个明亮的像素中嵌入一个计数器,使图像是唯一的:
img =(Image)fingerPrintID((Bitmap)img,250 - mailList.Count); // * 1 *
//现在我们添加文本:
int width = img.Width;
使用(Graphics G = Graphics.FromImage(img))
using(Font font = new Font(Arial,7f))
{
SizeF s = G.MeasureString (mailName,font,width);
G.DrawString(mailName,font,Brushes.Black,
(width-s.Width)/ 2,img.Height - s.Height - 1);

}
//添加图像很容易只有我们使用剪贴板。
Clipboard.SetImage(img);
//只在最后插入!
rTB_test.SelectionStart = rTB_test.TextLength;
rTB_test.SelectionLength = 0;
//现在插入图像
rTB_test.Paste();
//现在我们可以得到一个哈希码作为唯一的密钥..
// ..选择我们刚刚插入的图像:
rTB_test.SelectionStart = rTB_test.TextLength - 1;
rTB_test.SelectionLength = 1;
//检索计数器ID:
string id = GetID(rTB_test.SelectedRtf); // * 2 *
//最后我们需要使用其密钥存储邮件本身:
mailList.Add(id,mi);
// cleanup:取消选择并将游标设置为结束:
rTB_test.SelectionStart = rTB_test.TextLength;
rTB_test.SelectionLength = 0

我们需要创建一个字典来存储我们的邮件: / p>

 字典< string,Microsoft.Office.Interop.Outlook.MailItem> mailList = 
新词典< string,Microsoft.Office.Interop.Outlook.MailItem>(); // * 3 *

以下是我们如何访问DoubleClick事件中的邮件:

  private void rTB_test_DoubleClick(object sender,EventArgs e)
{
var ss = rTB_test.SelectionStart;
var sl = rTB_test.SelectionLength;
string id = GetID(sr); // * 4 *
//一些检查:
if(sl == 1&& mailList.Keys.Contains(id)&& sr.Contains(@{\ pict\))
{
Microsoft.Office.Interop.Outlook.MailItem mi = mailList [id];
//与msgItem做某事,例如
mi.Display();

}
}

图像我使用:



< img src =https://i.stack.imgur.com/ownB8.pngalt =mail>



请注意,除了添加图像之外,也将字体中的邮件数据和图像的位置存储在RTB中。



更新2:我已经替换了该位置的图像作为其RtfText的HashCode的关键;这对于RTF内容的其他部分的任何变化都是稳健的。但是,它依赖于图像是唯一的,因此建议在代码中添加索引到其文本。 (或设置几个随机像素,也许基于GUID ..)



更新3& 4:(* 1 * - * 6 *)



我们发现我们需要使密钥具有几个变化,例如围绕图标的字体,这将影响Rtf代码,或用户放大图像。



这里是一个FingerPrint功能,它将通过设置几个像素使我们添加的图像不受任何影响在图像的顶部。三个设置一个标记,一个设置一个ID:

  Bitmap fingerPrintID(Bitmap bmp,int key)// * 5 * 
{
for(int i = 0; i <3; i ++)
{
bmp.SetPixel(i,0,Color.FromArgb(255,238,238,238)); // EE EE EE
}
bmp.SetPixel(3,0,Color.FromArgb(255,key,key,key));
return bmp;
}

要检索此函数将从RTF中拉出3个十六进制数字作为字符串代码:

  string GetID(string Rtf)// * 6 * 
{
int x = Rtf .IndexOf( eeeeeeeeeeeeeeeeee); // 238 238 238
if(x< 0)return;
string hex = Rtf.Substring(x +18,6);
返回十六进制;
}

我选择的像素相当明亮;如果您知道使用哪种图像,您可以更加优化颜色选择。使用新的字符串ID,我们不需要GetHashcode调用..


I got a problem with my WinForms-Application; I want to Drag&Drop a Outlook Mail into a RichTextBox. I found many articles about the Drag&Drop function but they all insert the Mailtext into the rTB (see: Link).Actually I can insert document like .txt, .jpg, Outlook-mails from desktop... to my program. My richTextBox automatic generate an image for the file and insert this image on a position. Like:

.

After the user Drag and Drop the file a image will be created on the Drop position and if the user double click the image the file will be opened.

PROBLEM:

The program work fine, but if I try to drag a mail out of Outlook, the program insert the mailbody to the richTextBox and no as an image.

I have saved one Mail on the desktop and try to insert this mail to my program. The following output is given in my richTextBox (would be perfect):

Mailicon from desktop per Drag&Drop:

Otherwise I tried to Drag&Drop a mai from Outlook to my program and the following output is given (Just look at the text and not the images:

Mail from Outlook per Drag&Drop (THE PROBLEM!!!):

The Programm insert the cc/mailadress and Mailbody to the rTB.

Here is the code behind: (My richTextBox is a own created richTextBox called "MyRichTextBox" Download the project under: link_RICHTEXTBOX. )

CODE

    private void Form1DragDrop(object sender, DragEventArgs e)
            {
                Startup();
               //Microsoft.Office.Interop.Outlook.ApplicationClass oApp =
               //      new Microsoft.Office.Interop.Outlook.ApplicationClass();
               Microsoft.Office.Interop.Outlook.Explorer oExplorer = _Outlook.ActiveExplorer();
               Microsoft.Office.Interop.Outlook.Selection oSelection = oExplorer.Selection;

               foreach (object item in oSelection)
               {
                   Microsoft.Office.Interop.Outlook.MailItem mi = (Microsoft.Office.Interop.Outlook.MailItem)item;

                   rTB_test.Text = mi.Body.ToString();

                    string mailName = "Mail\n" + (mailList.Count + 1);
                    // load an image with enough room at the bottom to add some text:
                    Image img = Image.FromFile(Imagepath);
                    // now we add the text:
                    int width = img.Width;
                    using (Graphics G = Graphics.FromImage(img))
                    using (Font font = new Font("Arial", 7f))
                    {
                        SizeF s = G.MeasureString(mailName, font, width);
                        G.DrawString(mailName, font, Brushes.Black, 
                            (width - s.Width) / 2, img.Height - s.Height - 1);

                    }
                    // adding the image is easy only if we use the clipboard..
                    Clipboard.SetImage(img);
                    // now insert image
                    rTB_test.Paste();
                    // now we can get a hashcode as a unique key..
                    // ..we select the image we have just inserted:
                    rTB_test.SelectionStart = rTB_test.TextLength - 1;
                    rTB_test.SelectionLength = 1;
                    // finally we need to store the mail itself with its key:
                    mailList.Add(rTB_test.SelectedRtf.GetHashCode(), mi);   
                    // cleanup: unselect and set cursor to the end:
                    rTB_test.SelectionStart = rTB_test.TextLength;
                    rTB_test.SelectionLength = 0;
            }
        Microsoft.Office.Interop.Outlook.Application _Outlook = null;

        Dictionary<int, Microsoft.Office.Interop.Outlook.MailItem> mailList =
  new Dictionary<int, Microsoft.Office.Interop.Outlook.MailItem>();

        private void rTB_test_DoubleClick(object sender, EventArgs e)
        {
            var ss = rTB_test.SelectionStart;
            var sl = rTB_test.SelectionLength;
            int hash = rTB_test.SelectedRtf.GetHashCode();
            // a few checks:
            if (sl == 1 && mailList.Keys.Contains(hash))
            {
                Microsoft.Office.Interop.Outlook.MailItem mi = mailList[hash];
                // do stuff with the msgItem..
                // ..
            }
        }

        void lbl_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Microsoft.Office.Interop.Outlook.MailItem mi =
              (Microsoft.Office.Interop.Outlook.MailItem)((Label)sender).Tag;
            // code to process the doubleclicked mail item..
        }

        void Startup()
        {
            _Outlook = new Microsoft.Office.Interop.Outlook.Application();
        }

        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }

After the user double click on the picture the mail should be opened in Outlookexplorer.

UPDATE

If I use the code from TaW´s answer the following output is given:

After I double click the icon the mail won´t be open... So the code from the answer is just a "iconcreation". Thank you in advanced!

解决方案

Here is what I meant in my comments:

private void Form1DragDrop(object sender, DragEventArgs e)
{
   Startup();
   Microsoft.Office.Interop.Outlook.ApplicationClass oApp = 
         new Microsoft.Office.Interop.Outlook.ApplicationClass();
   Microsoft.Office.Interop.Outlook.Explorer oExplorer = _Outlook.ActiveExplorer();
   Microsoft.Office.Interop.Outlook.Selection oSelection = Explorer.Selection;

   foreach (object item in oSelection)          
   {
       Microsoft.Office.Interop.Outlook.MailItem mi = 
        (Microsoft.Office.Interop.Outlook.MailItem)item;
      //    rTB_test.Text = mi.Body.ToString();
      Label lbl = new Label();
      lbl.AutoSize = false;
      lbl.Size = new Size( 80, 50);         // <-- your choice!
      lbl.Text = someText;                 // <-- your choice!
      lbl.TextAlign = ContentAlignment.BottomCenter;
      lbl.Image = someImage;             // <-- your choice!
      lbl.ImageAlign = ContentAlignment.TopCenter;
      int count = rTB_test.Controls.Count;
      int itemsPerRow = rTB_test.Width / 80;
      lbl.Location = new Point( (count % itemsPerRow) * 80, 
                                 count / itemsPerRow * 50); 
      lbl.Tag = mi;               // store the data object
      lbl.MouseDoubleClick += lbl_MouseDoubleClick;
      lbl.Parent = rTB_test;     // add to the RTF's Controls
   }
}

void lbl_MouseDoubleClick(object sender, MouseEventArgs e)
{
   Microsoft.Office.Interop.Outlook.MailItem mi = 
     (Microsoft.Office.Interop.Outlook.MailItem) ( (Label)sender).Tag;
   // code to process the doubleclicked mail item..
}

These Labels will sit on top of any Text in the RTB without interfering with it. If you want to, you can modify the code for the Location to move them out of the way or style the Labels in many other ways..

Update

After the last remarks the problem get a lot clearer: other parts of the application are already adding mail icons to the RTB and we shall add more 'of the same'..

Adding an Image is best done via the clipboard; here is code that will do that:

// create some test text, maybe extract it from the mailheader?..
string mailName = "Mail\n" + (mailList.Count + 1);
// load an image with enough room at the bottom to add some text:
Image img = Image.FromFile(yourMailImageFile);
// make the images unique by embedding a counter in a bright pixel:
img = (Image)fingerPrintID((Bitmap)img, 250 - mailList.Count);      //*1*
// now we add the text:
int width = img.Width;
using (Graphics G = Graphics.FromImage(img))
using (Font font = new Font("Arial", 7f))
{
    SizeF s = G.MeasureString(mailName, font, width);
    G.DrawString(mailName, font, Brushes.Black, 
        (width - s.Width) / 2, img.Height - s.Height - 1);

}
// adding the image is easy only if we use the clipboard..
Clipboard.SetImage(img);
// insert only at the end!        
rTB_test.SelectionStart = rTB_test.TextLength;
rTB_test.SelectionLength = 0;
// now insert image
rTB_test.Paste();
// now we can get a hashcode as a unique key..
// ..we select the image we have just inserted:
rTB_test.SelectionStart = rTB_test.TextLength - 1;
rTB_test.SelectionLength = 1;
// retrieve the counter id:
string id = GetID(rTB_test.SelectedRtf);    //*2*
// finally we need to store the mail itself with its key:
mailList.Add(id, mi);   
// cleanup: unselect and set cursor to the end:
rTB_test.SelectionStart = rTB_test.TextLength;
rTB_test.SelectionLength = 0

We need to create a Dictionary to store our mails:

Dictionary<string, Microsoft.Office.Interop.Outlook.MailItem> mailList = 
  new Dictionary<string, Microsoft.Office.Interop.Outlook.MailItem>();  // *3*

Here is how we can access the mails in the DoubleClick event:

private void rTB_test_DoubleClick(object sender, EventArgs e)
{
    var ss = rTB_test.SelectionStart;
    var sl = rTB_test.SelectionLength;
    string id = GetID(sr);  //*4*
    // a few checks:
    if (sl == 1 &&  mailList.Keys.Contains(id) && sr.Contains(@"{\pict\") )
    {
       Microsoft.Office.Interop.Outlook.MailItem mi = mailList[id]; 
       // do stuff with the msgItem, e.g..
       mi.Display();

    }
}

Here is the result along with the image I use:

Note that in addition to adding the image we also store the both the mail data and the position of the image in the RTB in a Dictionary.

Update 2: I have replaced the position of the image as key with a HashCode of its RtfText; this is robust to any changes in the rest of the RTF's content. However, it relies on the images being unique, so adding an index to their text as in the code is recommended. (Or setting a few random pixels, maybe based on a GUID..)

Update 3 & 4: (*1* - *6*)

We found that we need to make the key resilient to several changes, like fonts surrounding the icon, which will influence the Rtf code, or the user enlarging the image.

Here is a FingerPrint function, which will make the images we add in unobtrusivly unique by setting a few pixels at the top of the image. Three to set a marker and one to set an ID:

Bitmap fingerPrintID(Bitmap bmp, int key)  //*5*
{
    for (int i = 0; i < 3; i++)
    {
        bmp.SetPixel(i, 0, Color.FromArgb(255, 238,238,238)); // EE EE EE
    }
    bmp.SetPixel(3, 0, Color.FromArgb(255, key, key, key));
    return bmp;
}

And to retrieve this function will pull the 3 hex digits as string from the RTF code:

string GetID(string Rtf)   //*6*
{
    int x = Rtf.IndexOf("eeeeeeeeeeeeeeeeee");  // 238 238 238
    if (x < 0) return "";
    string hex = Rtf.Substring(x +18, 6);
    return hex;
}

I chose the pixels to be rather bright; if you know which image you use, you can optimze the color choice even more.. With the new string id, we don't need the GetHashcode calls..

这篇关于如何将Outlook-Mail拖放到richTextBox中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆