Drag'n'drop files from (e.g. iPhone) in Windows Explorer to a WPF application

I have a C # WPF application that allows users to import files by dragging and dropping them from Windows Explorer and dropping them in the main application window.

It works great when dragging files from physical disks, but when dragging files from a connected device, such as an iPhone or camera connected via USB, I do not recognize any of the data formats returned by dragEventArgs.Data.GetFormats () to the Drop window handler.

Does anyone want to share some tips or point me to a good example or step-by-step guide on how to read / import files from a "virtual" file system into C # /. NET in this way?

Thank,

Dylan

+3
source share
1 answer

Getting file names

Getting file names is very simple. Just call:

dragEventArgs.Data.GetData("FileGroupDescriptorW")

this will return MemoryStreamwhich contains the structure FILEGROUPDESCRIPTORA. This can be analyzed to get file names. Here and here are links to CodeProject projects that show you two different ways to parse FILEGROUPDESCRIPTORAin C #, so I won’t go into details here. I would probably use the technique described in the first draft.

Obtaining Actual Data

, FileContents. , , COM-. , System.Runtime.InteropServices.ComTypes.IDataObject FORMATETC, lindex . , System.Windows.DataObject lindex = -1.

, , WPF DataObject. , NET Framework. , - RegisterDragDrop ole32.dll, IOleDropTarget, COM IDataObject, . , , , .NET Framework, .

, FileContent :

  • , , GetData,
  • , System.Windows.IDataObject, 1 ( ).
  • MethodInfo.Invoke "GetData", : "FileContents", false, ComTypes.DVASPECT, lindex
  • MemoryStream

:

public MemoryStream GetFileContents(IDataObject dataObject, int index)
{
  MethodInfo getData = (
    from method in dataObject.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
    where method.Name=="GetData" && method.GetParameters().Length==4
    select method
  ).FirstOrDefault();

  if(getData==null)
  {
    FieldInfo innerField = (
      from field in dataObject.GetType().GetFields()
      where field.FieldType == typeof(IDataObject)
      select field
    ).FirstOrDefault();
    if(innerField==null) throw new Exception("Cannot get FileContents from DataObject of type" + dataObject.GetType());
    return GetFileContents((IDataObject)innerField.GetValue(dataObject), index);
  }

  return (MemoryStream)getData.Invoke(dataObject, new object[]
  {
    "FileContents", false,
    System.Runtime.InteropServices.ComTypes.DVASPECT.DVASPECT_CONTENT,
    index
  });
}
+5

Source: https://habr.com/ru/post/1728233/


All Articles