Wpf 拖动操作到 Windows 资源管理器不起作用

问题描述 投票:0回答:0

我编写这段代码来执行从我的 wpf 应用程序到 Windows 资源管理器的 shell 样式文件拖动操作:

private void OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            DependencyObject src = (DependencyObject)(e.OriginalSource);
            while (!(src is Control))
            {
                src = VisualTreeHelper.GetParent(src);
            }
            string clicked_element_name = src.GetType().Name;

            if (clicked_element_name != "ListViewItem")
            {
                this.ExListView.UnselectAll();
                this.ExListView.Focus();
            }
            else
            {
                
                ListViewItem item = src as ListViewItem;
                FileExplorerItem explorerItem = item.Content as FileExplorerItem;
                CDataObject dataObject = new CDataObject();

                if (dataObject != null)
                {
                    List<string> filePaths = GetSelectedListViewItemsPaths();
                    String fileList = "";
                    foreach (string filePath in filePaths)
                    {
                        fileList += filePath + char.MinValue;
                        
                    }
                    fileList += char.MinValue;

                    // Allocate memory for the DROPFILES structure
                    int size = Marshal.SizeOf(typeof(DROPFILES)) + (fileList.Length + 2) *2; // Length of the string plus one for the double null terminator
                    IntPtr hGlobal = Marshal.AllocHGlobal(size);

                    // Initialize the DROPFILES structure
                    DROPFILES dropFiles = new DROPFILES();
                    unsafe
                    {
                        dropFiles.pFiles = sizeof(DROPFILES); // Offset to the file list
                    }
                    dropFiles.fWide = true; // Indicates that the file list is in Unicode format
                    byte[] dropFilesBuffer = new byte[size];
                    IntPtr dropFilesPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dropFiles));
                    Marshal.StructureToPtr(dropFiles, dropFilesPtr, true);
                    Marshal.Copy(dropFilesPtr, dropFilesBuffer, 0, Marshal.SizeOf(dropFiles));
                    Marshal.FreeHGlobal(dropFilesPtr);

                    // Copy the file list to the global memory
                    byte[] fileListBuffer = Encoding.Unicode.GetBytes(fileList.ToString());
                    Marshal.Copy(fileListBuffer, 0, hGlobal + Marshal.SizeOf(typeof(DROPFILES)), fileListBuffer.Length);

                    // Copy the DROPFILES structure to the global memory
                    Marshal.Copy(dropFilesBuffer, 0, hGlobal, dropFilesBuffer.Length);

                    System.Runtime.InteropServices.ComTypes.FORMATETC formatec = new System.Runtime.InteropServices.ComTypes.FORMATETC();
                    formatec.dwAspect = System.Runtime.InteropServices.ComTypes.DVASPECT.DVASPECT_CONTENT;
                    formatec.lindex = -1;
                    formatec.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_HGLOBAL;
                    formatec.cfFormat = (short)DataFormats.GetDataFormat(DataFormats.FileDrop).Id;

                    System.Runtime.InteropServices.ComTypes.STGMEDIUM stgmedium = new System.Runtime.InteropServices.ComTypes.STGMEDIUM();
                    stgmedium.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_HGLOBAL;
                    stgmedium.unionmember = hGlobal;

                    IntPtr hwnd = new WindowInteropHelper(Application.Current.MainWindow).Handle;
                    
                    dataObject.SetData(ref formatec, ref stgmedium, true);
                    
                    try
                    {
                        int hr = DragHelper.SHDoDragDrop(hwnd, dataObject, null, DragDropEffects.Copy, out var result);
                        if (hr < 0)
                        {
                            throw Marshal.GetExceptionForHR(hr);
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    Marshal.FreeHGlobal(hGlobal);
                }
                else
                {
                    // handle the case when dataObject is null
                }
            }
        }

在 Windows Exlporer 上执行了一次成功的删除,hResult 返回 262400,但是没有任何反应,文件没有被复制,就像从来没有发生过文件删除一样。 我的猜测是我向 DROPFILES 结构提供文件路径的方式有问题,但我无法弄清楚。

我尝试了不同的方法来为结构提供文件路径,但没有任何帮助。 也许有人可以引导我走上正确的道路?

c# wpf drag-and-drop com drag
© www.soinside.com 2019 - 2024. All rights reserved.