拖放时'无效的FORMATETC结构'C#

时间:2018-02-15 23:07:31

标签: c# drag-and-drop outlook-addin office-addins interopservices

我正在尝试在拖动操作开始时将dataObject的数据转换为CF_HDROP格式。我能够读取byteArray,我将在某些时候存储它,但是现在我正在硬编码实际存在于我的驱动器上的文件的路径。

我已使用此C# drag-drop problem作为参考。

这是我对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);

我尝试在非调试模式下运行应用程序&amp;验证了文件的完整性。我注意到DATADIR.DATADIR_SET没有返回任何可用的格式。这可能是问题吗?

编辑:当我尝试使用相同的formatEtc Object和用于读取数据的stgMedium对象时,似乎也会发生这种情况。

0 个答案:

没有答案