C#拖放问题

时间:2011-04-23 04:41:11

标签: c# drag-and-drop

我有一个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?

1 个答案:

答案 0 :(得分:2)

我决定使用.NET Interop实现IDataObject,从IDataObjec t here实现DROPFILES开始。然后我定义了[StructLayoutAttribute(LayoutKind.Sequential)] internal struct _DROPFILES { public Int32 pFiles; public Int32 X; public Int32 Y; public bool fNC; public bool fWide; } 结构

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

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

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; }

DataObject

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