Search code examples
c#imagewinformsdragsd-card

How To drag images directly from Camera or Smartphone to C# app?


I found a script (http://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C) that makes it possible to drag images to a c# application. (especially from outlook) The fileDrop format is used to copy (drag) images from my Hard disk to c# app. This works well when the images are stored on my hard disk, but when i try to drag the images directly from my storage card (from Camera or smartphone (like a Samsung S3)) it won't work. These are the drag formats i'm getting from those image(s):

(0): "Shell IDList Array"
(1): "FileContents"
(2): "FileGroupDescriptorW"
(3): "WPD Storage Attributes"
(4): "Preferred DropEffect"
(5): "WPD NSE"
(6): "WPD NSE PnPDevicePath"
(7): "WPD NSE StoragePUID"
(8): "UsingDefaultDragImage"
(9): "DragImageBits"
(10): "DragContext"
(11): "DragSourceHelperFlags"
(12): "InShellDragLoop"
(13): "IsShowingLayered"
(14): "DragWindow"
(15): "IsComputingImage"
(16): "DataObjectAttributes"
(17): "DisableDragText"
(18): "IsShowingText"
(19): "DropDescription"
(20): "ComputedDragImage"
(21): "Logical Performed DropEffect"
(22): "Performed DropEffect"
(23): "Paste Succeeded"

When i try to access the 'FileGroupDescriptorW' i'm receiving an Illegal access violation error. Also, 'FileGroupDescriptor' seems to be missing here? Could anyone help me resolve this issue? I searched this site and Google, but didn't find anything useful.


Solution

  • The solution was posted by John Schroedl and was hidden in the many reactions on the Topic.

    These two 'fixes' fixed my problem:

    http://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C?msg=3535951#xx3535951xx

    OLD C#:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public sealed class FILEGROUPDESCRIPTORA
    {
        public uint cItems;
        public FILEDESCRIPTORA[] fgd;
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public sealed class FILEGROUPDESCRIPTORW
    {
        public uint cItems;
        public FILEDESCRIPTORW[] fgd;
    }
    

    FIXED C#:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public sealed class FILEGROUPDESCRIPTORA
    {
        public uint cItems;
        public FILEDESCRIPTORA fgd;
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public sealed class FILEGROUPDESCRIPTORW
    {
        public uint cItems;
        public FILEDESCRIPTORW fgd;
    }
    

    And this fix: http://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C?msg=3551197#xx3551197xx

    Old:

    case "FileContents":
        //override the default handling of FileContents which returns the
        //contents of the first file as a memory stream and instead return
        //a array of MemoryStreams containing the data to each file dropped
    
        //get the array of filenames which lets us know how many file contents exist
        string[] fileContentNames = (string[])this.GetData("FileGroupDescriptor");
    

    Fix:

    case "FileContents":
        //override the default handling of FileContents which returns the
        //contents of the first file as a memory stream and instead return
        //a array of MemoryStreams containing the data to each file dropped
        //
        // FILECONTENTS requires a companion FILEGROUPDESCRIPTOR to be
        // available so we bail out if we don't find one in the data object.
    
        string fgdFormatName;
    
        if (GetDataPresent("FileGroupDescriptorW"))
            fgdFormatName = "FileGroupDescriptorW";
        else if (GetDataPresent("FileGroupDescriptor"))
            fgdFormatName = "FileGroupDescriptor";
        else
            return null;
    
        //get the array of filenames which lets us know how many file contents exist
        string[] fileContentNames = (string[])this.GetData(fgdFormatName);
    

    In case anyone needs it...