C#拖放问题

我有一个C#.NET 3.5应用程序,它允许从树中拖动项目并将它们作为文件放到文件夹中。 这是我的代码

String absolutePathToFile=...get absolute path DataObject dataObject = new DataObject(); StringCollection paths = new StringCollection(); paths.Add(absolutePathToFile); dataObject.SetFileDropList(paths); DoDragDrop(dataObject, DragDropEffects.Copy); 

这非常有效,除非与通过拖放接受文件的另一个C#应用程序交互时,另一个C#应用程序具有DragOver的以下处理程序

 if ((e.Data is DataObject) && (e.Data as DataObject).ContainsFileDropList()) { e.Effect = DragDropEffects.Copy; } 

永远不会执行该块,因为e.Data是__ComObject而不是DataObject。 有趣的是,当我从第二个应用程序的文件夹中拖动文件时,它将其视为DataObject。

如何从第一个C#应用程序使DataObject在第二个C#应用程序中显示为DataObject?

我决定使用.NET Interop从IDataObjec t实现开始实现IDataObject 。 然后我定义了DROPFILES结构

 [StructLayoutAttribute(LayoutKind.Sequential)] internal struct _DROPFILES { public Int32 pFiles; public Int32 X; public Int32 Y; public bool fNC; public bool fWide; } 

并实现填充所有OLE结构的代码。 下面的函数返回我在DoDragDrop中使用的IDataObject:

DoDragDrop(GetDataObject(new String[] { file name }), DragDropEffects.Copy);

 DataObject2 GetDataObject(String[] strFiles) { byte[] bData; _DROPFILES df = new _DROPFILES(); int intChar, intFile, intDataLen, intPos; IntPtr ipGlobal = IntPtr.Zero; // Calculate total data length intDataLen = 0; for (intFile = 0; intFile <= strFiles.GetUpperBound(0);intFile++) { intDataLen += strFiles[intFile].Length + 1; } // Terminating double zero intDataLen++; bData = new Byte[intDataLen]; intPos = 0; // Build null terminated list of files for (intFile = 0; intFile <= strFiles.GetUpperBound(0); intFile++) { for (intChar = 0; intChar < strFiles[intFile].Length;intChar++) { bData[intPos++] = (byte)strFiles[intFile][intChar]; } bData[intPos++] = 0; } // Terminating double zero bData[intPos++] = 0; // Allocate and get pointer to global memory int intTotalLen = Marshal.SizeOf(df) + intDataLen; ipGlobal = Marshal.AllocHGlobal(intTotalLen); if (ipGlobal == IntPtr.Zero) { return null; } // Build DROPFILES structure in global memory. df.pFiles = Marshal.SizeOf(df); df.fWide = false; Marshal.StructureToPtr(df, ipGlobal, true); IntPtr ipNew = new IntPtr(ipGlobal.ToInt32() + Marshal.SizeOf(df)); Marshal.Copy(bData, 0, ipNew, intDataLen); short CF_HDROP = 15; System.Runtime.InteropServices.ComTypes.FORMATETC formatEtc; System.Runtime.InteropServices.ComTypes.STGMEDIUM stgMedium; formatEtc = new System.Runtime.InteropServices.ComTypes.FORMATETC(); formatEtc.cfFormat = CF_HDROP; formatEtc.dwAspect = System.Runtime.InteropServices.ComTypes.DVASPECT.DVASPECT_CONTENT; formatEtc.lindex = -1; formatEtc.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_HGLOBAL; stgMedium = new System.Runtime.InteropServices.ComTypes.STGMEDIUM(); stgMedium.unionmember = ipGlobal; stgMedium.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_HGLOBAL; DataObject2 dobj = new DataObject2(); dobj.SetData(ref formatEtc, ref stgMedium, false); return dobj; } 

使用新代码第二个应用程序在e.Data看到DataObject ,我可以将文件拖放到任何应用程序。 除了现在资源管理器不接受文件。 我的实施中是否会遗漏一些内容?