简体   繁体   中英

how to drag and save outlook email into WPF application

I am creating a WPF application. i want to drag email from outlook into this wpf application and application needs to save it in a specific folder. i have tried using http://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C article. It works fine for winform. i tried using same code in WPF after fixing all compile time bugs but still it is not working.

I have searched web a lot but cannot find any working solution for this problem. Can someone please provide any working sample code?

!!! Add references: " Microsoft.Office.Interop.Outlook.dll " !!! (Search in your disks)

Analyzee your DragObject:

WPF:

<Window x:Class="WpfApplication1.MainWindow"
        x:Name="thisForm"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <TextBlock TextWrapping="WrapWithOverflow" Drop="ContainerDrop" DragOver="ContainerDragOver" Name="f_DropText" AllowDrop="True"/>
</Window>

c#

using System;
using System.IO;
using System.Text;
using System.Windows;
namespace WpfApplication1
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
    }
    private void ContainerDrop(object sender, DragEventArgs e)
    {
      f_DropText.Text = "";
      StringBuilder sb = new StringBuilder();
      foreach (string format in e.Data.GetFormats())
      {
        sb.AppendLine("Format:" + format);
        try
        {
          object data = e.Data.GetData(format);
          sb.AppendLine("Type:" + (data == null ? "[null]" : data.GetType().ToString()));
          if (format == "FileGroupDescriptor")
          {
            Microsoft.Office.Interop.Outlook.Application OL = new Microsoft.Office.Interop.Outlook.Application();
            sb.AppendLine("##################################################");
            for (int i = 1; i <= OL.ActiveExplorer().Selection.Count; i++)
            {
              Object temp = OL.ActiveExplorer().Selection[i];
              if (temp is Microsoft.Office.Interop.Outlook.MailItem)
              {
                Microsoft.Office.Interop.Outlook.MailItem mailitem = (temp as Microsoft.Office.Interop.Outlook.MailItem);
                int n=1;
                sb.AppendLine("Mail " + i + ": " + mailitem.Subject);
                foreach (Microsoft.Office.Interop.Outlook.Attachment attach in mailitem.Attachments)
                {
                  sb.AppendLine("File " + i + "."+n+": " + attach.FileName);
                  sb.AppendLine("Size " + i + "."+n+": " + attach.Size);
                  sb.AppendLine("For save using attach.SaveAsFile");
                  ++n;
                }
              }
            }
            sb.AppendLine("##################################################");
          }
          else
            sb.AppendLine("Data:" + data.ToString());
        }
        catch (Exception ex)
        {
          sb.AppendLine("!!CRASH!! " + ex.Message);
        }
        sb.AppendLine("=====================================================");
      }
      f_DropText.Text = sb.ToString();
    }
    private void ContainerDragOver(object sender, DragEventArgs e)
    {
      e.Effects = DragDropEffects.Copy;
      e.Handled = true;
    }
  }
}

Finally, I got this working.

I took this guys code at http://www.codeproject.com/KB/office/outlook_drag_drop_in_cs.aspx and altered it to work with WPF.

But it was not easy since there were few constructs that had changed in the underlying COM constructs of System.Windows, so it did not work just by changing from system.windows to swforms.IDataObject.

Then I found this github code from this thread
https://social.msdn.microsoft.com/Forums/vstudio/en-US/5853bfc1-61ac-4c20-b36c-7ac500e4e2ed/how-to-drag-and-drop-email-msg-from-outlook-to-wpfor-activex-for-upload-and-send-them-out-via?forum=wpf

http://gist.github.com/521547 - This is the new IDataObject that works with WPF .

Has corrections to accomodate System.Windows.IDataObject instead of SWForms.IDataObject and '_innerData' should be used to query for data, along with fixes for some memory access issues. The guy has nailed it !

Instead of trying to recover the dropped mail item object you need to detect that something was fropped from Outlook and then connect to the running Outlook instance using the System.Runtime.InteropServices.Marshal.GetActiveObject() method which obtains a running instance of the specified object from the running object table (ROT).

Then you can get the Selection object using the Selection property of the Explorer class. It returns a Selection object that contains the item or items that are selected in the explorer window.

 private void lbAttachments_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
        {
            e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent("FileGroupDescriptor") ? DragDropEffects.All : DragDropEffects.None;
        }

        private void lbAttachments_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
        {
            if (e.Data.GetDataPresent("FileGroupDescriptor"))
            {
                try {
                    var dataObject = new OutlookDataObject(e.Data);
                    var filePaths = new StringCollection();

                    string[] fileContentNames = (string[])dataObject.GetData("FileGroupDescriptor");
                    if (fileContentNames.Count() > 0)
                    {
                        var fileStreams = (MemoryStream[])dataObject.GetData("FileContents");

                        for (int fileIndex = 0; fileIndex < fileContentNames.Length; fileIndex++)
                        {
                            var ms = fileStreams[fileIndex];
                            var bytes = ms.ToArray();

                            AddAttachment(fileContentNames[fileIndex], bytes);
                        }
                    }
                }
                catch(Exception) { /* ignore */ }

            }
            else if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] s = (string[])e.Data.GetData(DataFormats.FileDrop);
                if (s == null)
                    return;

                foreach (string file in s)
                    AddAttachment(file);
            }
private void AddAttachment(string argFilename)
        {
            var daten = File.ReadAllBytes(argFilename);
            AddAttachment(argFilename, daten);
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM