<bdo id='LivzW'></bdo><ul id='LivzW'></ul>
  • <tfoot id='LivzW'></tfoot>
  • <small id='LivzW'></small><noframes id='LivzW'>

        <legend id='LivzW'><style id='LivzW'><dir id='LivzW'><q id='LivzW'></q></dir></style></legend>

      1. <i id='LivzW'><tr id='LivzW'><dt id='LivzW'><q id='LivzW'><span id='LivzW'><b id='LivzW'><form id='LivzW'><ins id='LivzW'></ins><ul id='LivzW'></ul><sub id='LivzW'></sub></form><legend id='LivzW'></legend><bdo id='LivzW'><pre id='LivzW'><center id='LivzW'></center></pre></bdo></b><th id='LivzW'></th></span></q></dt></tr></i><div id='LivzW'><tfoot id='LivzW'></tfoot><dl id='LivzW'><fieldset id='LivzW'></fieldset></dl></div>

      2. 使用 IStream 拖放虚拟文件

        时间:2023-08-25
      3. <i id='7R0Tg'><tr id='7R0Tg'><dt id='7R0Tg'><q id='7R0Tg'><span id='7R0Tg'><b id='7R0Tg'><form id='7R0Tg'><ins id='7R0Tg'></ins><ul id='7R0Tg'></ul><sub id='7R0Tg'></sub></form><legend id='7R0Tg'></legend><bdo id='7R0Tg'><pre id='7R0Tg'><center id='7R0Tg'></center></pre></bdo></b><th id='7R0Tg'></th></span></q></dt></tr></i><div id='7R0Tg'><tfoot id='7R0Tg'></tfoot><dl id='7R0Tg'><fieldset id='7R0Tg'></fieldset></dl></div>

            <tbody id='7R0Tg'></tbody>
          • <bdo id='7R0Tg'></bdo><ul id='7R0Tg'></ul>
            <legend id='7R0Tg'><style id='7R0Tg'><dir id='7R0Tg'><q id='7R0Tg'></q></dir></style></legend>

          • <tfoot id='7R0Tg'></tfoot>

                <small id='7R0Tg'></small><noframes id='7R0Tg'>

                  本文介绍了使用 IStream 拖放虚拟文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我想启用从基于 Windows 窗体的应用程序到 Windows 资源管理器的拖放功能.大问题:文件存储在数据库中,所以我需要使用延迟数据渲染.codeproject.com上有一篇文章,但是作者使用的是H_GLOBAL对象,这会导致文件大于 aprox 的内存问题.20 MB.我还没有找到使用 IStream 对象的可行解决方案.我认为这一定是可以实现的,因为这不是一个不寻常的情况.(例如,FTP 程序也需要这样的功能)

                  I want to enable drag and drop from our windows forms based application to Windows Explorer. The big problem: The files are stored in a database, so I need to use delayed data rendering. There is an article on codeproject.com, but the author is using a H_GLOBAL object which leads to memory problems with files bigger than aprox. 20 MB. I haven't found a working solution for using an IStream Object instead. I think this must be possible to implement, because this isn't an unusual case. (A FTP program needs such a feature too, for example)

                  是否可以在用户删除文件时获取事件?所以我可以例如将它复制到 temp 并且资源管理器从那里获取它?也许有另一种方法可以解决我的问题...

                  Is it possible to get an event when the user drops the file? So I could for example copy it to temp and the explorer gets it from there? Maybe there is an alternative approach for my problem...

                  推荐答案

                  AFAIK,没有关于.net 的工作文章.所以你应该自己写,这有点复杂,因为.net DataObject 类是有限的.我有相反任务的工作示例(接受来自资源管理器的延迟渲染文件),但它更容易,因为我不需要自己的 IDataObject 实现.

                  AFAIK, there is not working article about this for .net. So you should write it by yourself, this is somewhat complicate, because .net DataObject class is limited. I have working example of the opposite task (accepting delayed rendering files from explorer), but it is easier, because I do not needed own IDataObject implementation.

                  所以你的任务是:

                  1. 在 .net 中查找有效的 IDataObject 实现.我建议你看看 这里(.NET 中的 Shell 样式拖放(WPF 和 WinForms))
                  2. 您还需要一个用于托管流的 IStream 包装器(实现起来相对容易)
                  3. 使用来自 MSDN(Shell 剪贴板)的信息实现延迟呈现格式)

                  这是一个起点,并且通常提供足够的信息来实现此类功能.有一点耐心和几次不成功的尝试,你会做到的:)

                  This is the starting point, and in general enough information to implement such feature. With bit of patience and several unsuccessful attempts you will do it :)

                  更新:以下代码缺少很多必要的方法和函数,但主要逻辑在此.

                  Update: The following code lacks many necessary methods and functions, but the main logic is here.

                  // ...
                  
                  private static IEnumerable<IVirtualItem> GetDataObjectContent(System.Windows.Forms.IDataObject dataObject)
                  {
                    if (dataObject == null)
                      return null;
                  
                    List<IVirtualItem> Result = new List<IVirtualItem>();
                  
                    bool WideDescriptor = dataObject.GetDataPresent(ShlObj.CFSTR_FILEDESCRIPTORW);
                    bool AnsiDescriptor = dataObject.GetDataPresent(ShlObj.CFSTR_FILEDESCRIPTORA);
                  
                    if (WideDescriptor || AnsiDescriptor)
                    {
                      IDataObject NativeDataObject = dataObject as IDataObject;
                      if (NativeDataObject != null)
                      {
                        object Data = null;
                        if (WideDescriptor)
                          Data = dataObject.GetData(ShlObj.CFSTR_FILEDESCRIPTORW);
                        else
                          if (AnsiDescriptor)
                            Data = dataObject.GetData(ShlObj.CFSTR_FILEDESCRIPTORA);
                  
                        Stream DataStream = Data as Stream;
                        if (DataStream != null)
                        {
                          Dictionary<string, VirtualClipboardFolder> FolderMap =
                            new Dictionary<string, VirtualClipboardFolder>(StringComparer.OrdinalIgnoreCase);
                  
                          BinaryReader Reader = new BinaryReader(DataStream);
                          int Count = Reader.ReadInt32();
                          for (int I = 0; I < Count; I++)
                          {
                            VirtualClipboardItem ClipboardItem;
                  
                            if (WideDescriptor)
                            {
                              FILEDESCRIPTORW Descriptor = ByteArrayHelper.ReadStructureFromStream<FILEDESCRIPTORW>(DataStream);
                              if (((Descriptor.dwFlags & FD.FD_ATTRIBUTES) > 0) && ((Descriptor.dwFileAttributes & FileAttributes.Directory) > 0))
                                ClipboardItem = new VirtualClipboardFolder(Descriptor);
                              else
                                ClipboardItem = new VirtualClipboardFile(Descriptor, NativeDataObject, I);
                            }
                            else
                            {
                              FILEDESCRIPTORA Descriptor = ByteArrayHelper.ReadStructureFromStream<FILEDESCRIPTORA>(DataStream);
                              if (((Descriptor.dwFlags & FD.FD_ATTRIBUTES) > 0) && ((Descriptor.dwFileAttributes & FileAttributes.Directory) > 0))
                                ClipboardItem = new VirtualClipboardFolder(Descriptor);
                              else
                                ClipboardItem = new VirtualClipboardFile(Descriptor, NativeDataObject, I);
                            }
                  
                            string ParentFolder = Path.GetDirectoryName(ClipboardItem.FullName);
                            if (string.IsNullOrEmpty(ParentFolder))
                              Result.Add(ClipboardItem);
                            else
                            {
                              VirtualClipboardFolder Parent = FolderMap[ParentFolder];
                              ClipboardItem.Parent = Parent;
                              Parent.Content.Add(ClipboardItem);
                            }
                  
                            VirtualClipboardFolder ClipboardFolder = ClipboardItem as VirtualClipboardFolder;
                            if (ClipboardFolder != null)
                              FolderMap.Add(PathHelper.ExcludeTrailingDirectorySeparator(ClipboardItem.FullName), ClipboardFolder);
                          }
                        }
                      }
                    }
                  
                    return Result.Count > 0 ? Result : null;
                  }
                  
                  // ...
                  
                  public VirtualClipboardFile : VirtualClipboardItem, IVirtualFile
                  {
                    // ...
                  
                  public Stream Open(FileMode mode, FileAccess access, FileShare share, FileOptions options, long startOffset)
                  {
                    if ((mode != FileMode.Open) || (access != FileAccess.Read))
                      throw new ArgumentException("Only open file mode and read file access supported.");
                  
                    System.Windows.Forms.DataFormats.Format Format = System.Windows.Forms.DataFormats.GetFormat(ShlObj.CFSTR_FILECONTENTS);
                    if (Format == null)
                      return null;
                  
                    FORMATETC FormatEtc = new FORMATETC();
                    FormatEtc.cfFormat = (short)Format.Id;
                    FormatEtc.dwAspect = DVASPECT.DVASPECT_CONTENT;
                    FormatEtc.lindex = FIndex;
                    FormatEtc.tymed = TYMED.TYMED_ISTREAM | TYMED.TYMED_HGLOBAL;
                  
                    STGMEDIUM Medium;
                    FDataObject.GetData(ref FormatEtc, out Medium);
                  
                    try
                    {
                      switch (Medium.tymed)
                      {
                        case TYMED.TYMED_ISTREAM:
                          IStream MediumStream = (IStream)Marshal.GetTypedObjectForIUnknown(Medium.unionmember, typeof(IStream));
                          ComStreamWrapper StreamWrapper = new ComStreamWrapper(MediumStream, FileAccess.Read, ComRelease.None);
                  
                          // Seek from beginning
                          if (startOffset > 0)
                            if (StreamWrapper.CanSeek)
                              StreamWrapper.Seek(startOffset, SeekOrigin.Begin);
                            else
                            {
                              byte[] Null = new byte[256];
                              int Readed = 1;
                              while ((startOffset > 0) && (Readed > 0))
                              {
                                Readed = StreamWrapper.Read(Null, 0, (int)Math.Min(Null.Length, startOffset));
                                startOffset -= Readed;
                              }
                            }
                  
                          StreamWrapper.Closed += delegate(object sender, EventArgs e)
                          {
                            ActiveX.ReleaseStgMedium(ref Medium);
                            Marshal.FinalReleaseComObject(MediumStream);
                          };
                  
                          return StreamWrapper;
                        case TYMED.TYMED_HGLOBAL:
                          byte[] FileContent;
                  
                          IntPtr MediumLock = Windows.GlobalLock(Medium.unionmember);
                          try
                          {
                            long Size = FSize.HasValue ? FSize.Value : Windows.GlobalSize(MediumLock).ToInt64();
                            FileContent = new byte[Size];
                            Marshal.Copy(MediumLock, FileContent, 0, (int)Size);
                          }
                          finally
                          {
                            Windows.GlobalUnlock(Medium.unionmember);
                          }
                          ActiveX.ReleaseStgMedium(ref Medium);
                  
                          Stream ContentStream = new MemoryStream(FileContent, false);
                          ContentStream.Seek(startOffset, SeekOrigin.Begin);
                  
                          return ContentStream;
                        default:
                          throw new ApplicationException(string.Format("Unsupported STGMEDIUM.tymed ({0})", Medium.tymed));
                      }
                    }
                    catch
                    {
                      ActiveX.ReleaseStgMedium(ref Medium);
                      throw;
                    }
                  }
                  
                  // ...
                  

                  这篇关于使用 IStream 拖放虚拟文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:ItemsControl 拖放 下一篇:我可以为 C# Windows 应用程序拖放功能选择自定义

                  相关文章

                  最新文章

                1. <small id='NxE7v'></small><noframes id='NxE7v'>

                  <i id='NxE7v'><tr id='NxE7v'><dt id='NxE7v'><q id='NxE7v'><span id='NxE7v'><b id='NxE7v'><form id='NxE7v'><ins id='NxE7v'></ins><ul id='NxE7v'></ul><sub id='NxE7v'></sub></form><legend id='NxE7v'></legend><bdo id='NxE7v'><pre id='NxE7v'><center id='NxE7v'></center></pre></bdo></b><th id='NxE7v'></th></span></q></dt></tr></i><div id='NxE7v'><tfoot id='NxE7v'></tfoot><dl id='NxE7v'><fieldset id='NxE7v'></fieldset></dl></div>
                2. <tfoot id='NxE7v'></tfoot>

                  • <bdo id='NxE7v'></bdo><ul id='NxE7v'></ul>

                    1. <legend id='NxE7v'><style id='NxE7v'><dir id='NxE7v'><q id='NxE7v'></q></dir></style></legend>