我的 WinForms 应用程序有问题;我想将 Outlook 邮件拖放到 RichTextBox 中。我找到了很多关于拖放功能的文章,但它们都将 Mailtext 插入到 rTB(参见:Link)。实际上我可以从桌面插入 .txt、.jpg、Outlook 邮件等文档……到我的程序。我的 richTextBox 自动为文件生成图像并将该图像插入到某个位置。喜欢:
.
用户拖放文件后,将在放置位置创建一个图像,如果用户双击该图像,文件将被打开。
问题:
该程序运行良好,但如果我尝试将邮件拖出 Outlook,该程序会将邮件正文插入到 richTextBox 而不是图像。
我在桌面上保存了一封邮件,并尝试将这封邮件插入到我的程序中。我的 richTextBox 中给出了以下输出(这将是完美的):
通过拖放操作来自桌面的 Mailicon:
否则我尝试从 Outlook 中拖放一个 mai 到我的程序并给出以下输出(只看文本而不是图像:
通过拖放从 Outlook 发送邮件(问题!!!):
程序将 cc/mailadress 和 Mailbody 插入 rTB。
这是背后的代码:(我的 richTextBox 是一个自己创建的名为“MyRichTextBox”的 richTextBox 下载项目:link_RICHTEXTBOX。)
代码
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;
}
用户双击图片后,邮件将在 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 (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..
}
这些标签将位于 RTB 中任何文本的顶部,而不会干扰它。如果需要,您可以修改 Location 的代码以将它们移开或以许多其他方式设置 Labels 的样式。
更新
在最后一句话之后,问题变得更加清晰:应用程序的其他部分已经在向 RTB 添加邮件图标,我们将添加更多“相同的”..
最好通过剪贴板添加图像;这是将执行此操作的代码:
// 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
我们需要创建一个字典来存储我们的邮件:
Dictionary<string, Microsoft.Office.Interop.Outlook.MailItem> mailList =
new Dictionary<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*
// 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();
}
}
这是结果以及我使用的图像:
请注意,除了添加图像外,我们还将邮件数据和图像在 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);
return hex;
}
我选择的像素比较亮;如果你知道你使用的是哪个图像,你可以进一步优化颜色选择。使用新的字符串 id,我们不需要 GetHashcode 调用。
关于c# - 如何将 Outlook-Mail 拖放到 richTextBox 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28025923/