1

当拖动操作开始时,我正在尝试将 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 对象来读取数据而不做任何更改时,似乎也会发生这种情况。

4

0 回答 0