当拖动操作开始时,我正在尝试将 dataObject 的数据转换为 CF_HDROP 格式。我能够读取我将在某个时候存储的 byteArray,但现在我正在硬编码驱动器上实际存在的文件的路径。
我使用了这个C# 拖放问题作为参考。
这是我对 OleDragEnter 函数的实现:
public int OleDragEnter(object pDataObj, int grfKeyState, long pt, ref int pdwEffect)
{
if (pDataObj is IDataObject dataOb)
{
IEnumFORMATETC formatetc = dataOb.EnumFormatEtc(DATADIR.DATADIR_GET);
List<FORMATETC> formatetcList = GetFormatEtcList(formatetc);
if (formatetcList.Exists(f => f.tymed == TYMED.TYMED_ISTREAM))
{
FORMATETC iStreamFormatetc = formatetcList.Find(f => f.tymed == TYMED.TYMED_ISTREAM);
dataOb.GetData(ref iStreamFormatetc, out var stgmedium);
MemoryStream memStream = GetIStream(stgmedium);
byte[] rawData = memStream.ToArray(); //I will store this on the drive at somepoint
var fileName = StreamHelpers.GetFullFileName(); //Constant for now
String[] strFiles = {fileName};
_DROPFILES dropFiles = new _DROPFILES();
int intChar, intFile, intDataLen, intPos;
IntPtr ipGlobal = IntPtr.Zero;
intDataLen = 0;
for (intFile = 0; intFile <= strFiles.GetUpperBound(0); intFile++)
{
intDataLen += strFiles[intFile].Length + 1;
}
intDataLen++;
var byteData = new Byte[intDataLen];
intPos = 0;
for (intFile = 0; intFile <= strFiles.GetUpperBound(0); intFile++)
{
for (intChar = 0; intChar < strFiles[intFile].Length; intChar++)
{
byteData[intPos++] = (byte)strFiles[intFile][intChar];
}
byteData[intPos++] = 0;
}
byteData[intPos++] = 0;
int intTotalLen = Marshal.SizeOf(dropFiles) + intDataLen;
ipGlobal = Marshal.AllocHGlobal(intTotalLen);
if (ipGlobal == IntPtr.Zero)
{
return -1;
}
dropFiles.pFiles = Marshal.SizeOf(dropFiles);
dropFiles.fWide = false;
Marshal.StructureToPtr(dropFiles, ipGlobal, false);
IntPtr ipNew = new IntPtr(ipGlobal.ToInt32() + Marshal.SizeOf(dropFiles));
Marshal.Copy(byteData, 0, ipNew, intDataLen);
var formatEtc = new FORMATETC
{
cfFormat = (short) CLIPFORMAT.CF_HDROP, //15
dwAspect = DVASPECT.DVASPECT_CONTENT,
lindex = -1,
tymed = TYMED.TYMED_HGLOBAL,
ptd = IntPtr.Zero
};
var stgMedium = new STGMEDIUM
{
unionmember = ipGlobal,
tymed = TYMED.TYMED_HGLOBAL,
pUnkForRelease = IntPtr.Zero
};
dataOb.SetData(ref formatEtc, ref stgMedium, false);
}
}
return 0;
}
我不断收到“无效的 FORMATETC 结构”错误:
dataOb.SetData(ref formatEtc, ref stgMedium, false);
我尝试在非调试模式下运行应用程序并验证文件的完整性。我注意到 DATADIR.DATADIR_SET 不返回任何可用的格式。这可能是问题吗?
编辑:当我尝试使用相同的 formatEtc 对象和 stgMedium 对象来读取数据而不做任何更改时,似乎也会发生这种情况。