Перетаскивание с переносного устройства Windows в приложение WPF

Я работаю над приложением WPF, которое позволяет пользователю перетаскивать файлы из проводника Windows. Для обычных файлов я могу получить доступ к пути, используя
string[] fileNames = (string[])e.Data.GetData(DataFormats.FileDrop, false);

Но для файлов WPD он возвращает ноль. Я пытался следовать решению, указанному в http://us.generation-nt.com/answer/drag-drop-pictures-wpd-camera-help-31497882.html, но не смог заставить его работать. Я получаю AccessVoilationException при попытке получить количество элементов из массива Shell. Я разместил вопрос в MSDN ( http://social.msdn.microsoft.com/Forums/vstudio/en-US/ef7fc152-dd1b-4774-adb7-47b48726daea/drag-drop-from-windows-portable-device-to-wpf-application?forum=wpf), но потенциальных клиентов не было.

Есть ли что-то, что я здесь скучаю? Не могли бы вы помочь мне решить эту проблему?

Ниже приведена соответствующая часть моего кода.

public enum SIGDN : uint
    {
        NORMALDISPLAY = 0,
        PARENTRELATIVEPARSING = 0x80018001,
        PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
        DESKTOPABSOLUTEPARSING = 0x80028000,
        PARENTRELATIVEEDITING = 0x80031001,
        DESKTOPABSOLUTEEDITING = 0x8004c000,
        FILESYSPATH = 0x80058000,
        URL = 0x80068000
    }

    internal class IIDGuid
    {
        private IIDGuid() { } // Avoid FxCop violation AvoidUninstantiatedInternalClasses
        // IID GUID strings for relevant COM interfaces
        internal const string IModalWindow = "b4db1657-70d7-485e-8e3e-6fcb5a5c1802";
        internal const string IFileDialog = "42f85136-db7e-439c-85f1-e4075d135fc8";
        internal const string IFileOpenDialog = "d57c7288-d4ad-4768-be02-9d969532d960";
        internal const string IFileSaveDialog = "84bccd23-5fde-4cdb-aea4-af64b83d78ab";
        internal const string IFileDialogEvents = "973510DB-7D7F-452B-8975-74A85828D354";
        internal const string IShellItem = "43826D1E-E718-42EE-BC55-A1E261C37BFE";
        internal const string IShellItemArray = "B63EA76D-1F85-456F-A19C-48159EFA858B";
    }

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
    public interface IShellItem
    {
        void BindToHandler(IntPtr pbc,
            [MarshalAs(UnmanagedType.LPStruct)]Guid bhid,
            [MarshalAs(UnmanagedType.LPStruct)]Guid riid,
            out IntPtr ppv);

        void GetParent(out IShellItem ppsi);

        void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);

        void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);

        void Compare(IShellItem psi, uint hint, out int piOrder);
    };

   [ComImport]
    [Guid(IIDGuid.IShellItemArray)]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IShellItemArray
    {
        // Not supported: IBindCtx

        void BindToHandler([In, MarshalAs(UnmanagedType.Interface)] IntPtr pbc, [In] ref Guid rbhid, [In] ref Guid riid, out IntPtr ppvOut);

        void GetPropertyStore([In] int Flags, [In] ref Guid riid, out IntPtr ppv);

        void GetCount(out uint pdwNumItems);

        void GetItemAt([In] uint dwIndex, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);

        void EnumItems([MarshalAs(UnmanagedType.Interface)] out IntPtr ppenumShellItems);
    }

    [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern int SHCreateShellItemArrayFromDataObject(
                System.Runtime.InteropServices.ComTypes.IDataObject pdo,
                ref Guid riid,
                [MarshalAs(UnmanagedType.Interface)] out IShellItemArray ppv);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern Int32 GetLastError();


    private void OnFileDrop(object sender, DragEventArgs e)
    {
        string[] fileNames = (string[])e.Data.GetData(DataFormats.FileDrop, false);// null
        System.Runtime.InteropServices.ComTypes.IDataObject mydata = e.Data as System.Runtime.InteropServices.ComTypes.IDataObject;
        IShellItemArray nativeShellItemArray;
        Guid guid = new Guid(IIDGuid.IShellItemArray);
        int retCode = SHCreateShellItemArrayFromDataObject(mydata, ref guid, out nativeShellItemArray);
        IShellItem nativeShellItem;

       if (retCode == 0)
        {
            IntPtr displayname;

            uint items = 0;
            try
            {
                nativeShellItemArray.GetCount(out items); //Getting AccessVoilationException in this line
            }
            catch (Exception ex)
            {

            }
            if (items > 0)
            {
                for (uint item = 0; item < items; item++)
                {
                    nativeShellItemArray.GetItemAt(item, out nativeShellItem);

                    nativeShellItem.GetDisplayName(SIGDN.DESKTOPABSOLUTEPARSING, out displayname);
                    //Do something
                }

            }
        }
    }

0 ответов

Другие вопросы по тегам