将设置为(not )TVirtualStringTree
时是否可以将节点从拖放到VCL控件中DragType
dtOLE
dtVCL
我遇到这样的情况,我需要能够将节点从一个VT拖到另一个VT(dtOLE
可以正常工作),但是同时,在拖动的同时,我需要一个能够将节点放入一个TListBox
(或其他VCL)的选项。控制)。
我尝试DragAcceptFiles()
为该TListBox
句柄设置API ,但没有任何效果。
如何做呢?
上没有DragAcceptFiles
属性TListBox
。如果您要DragAcceptFiles()
在TListBox.Handle
窗口上调用Win32 API函数,则仅在以下情况下有效:
您可以手动将TListBox.WindowProc
属性子类化以处理WM_DROPFILES
窗口消息。
TVirtualStringTree
提供CF_HDROP
OLE拖动过程中的格式。
但是2不是正确的。CF_HDROP
仅用于拖动文件系统路径,而不能TVirtualStringTree
拖动。所以DragAcceptFiles()
用完了。
TVirtualStringTree
(和其他TBaseVirtualTree
后代)在OLE拖动期间使用自定义数据格式(VirtualTrees.pas
单元的接口部分声明了这些格式ID,因此您无需在自己的代码中手动注册它们):
CF_VIRTUALTREE
包含被拖动的选定树节点的IStream
或HGLOBAL
持有序列化形式。序列化由一系列描述每个节点的数据块组成。您将必须参考VirtualTree.pas
单元的实现来解密这种格式(我在这里不打算这样做)。
CF_VTREFERENCE
包含一个HGLOBAL
保存TVTReference
记录(该记录也在该VirtualTrees.pas
单元的接口部分中声明),该记录包含一个指向要TBaseVirtualTree
拖动的实际对象的指针以及该树所属的进程的ID。
因此,为了使您能够将树节点拖放到上TListBox
,您必须执行以下操作:
编写一个实现该IDropTarget
接口的类(或使用一个预先存在的实现,例如来自Anders Melander的Drag&Drop套件的实现)。
使用在TListBox.Handle
窗口中注册该类RegisterDragDrop()
。
在您的IDropTarget
实现中,您可以查询提供IDataObject
的CF_VIRTUALTREE
和CF_VTREFERENCE
格式。如果成功,您的Drop()
方法将有权访问被拖动的树节点数据,并可以TListBox
根据需要将其复制到中。
假设您的TListBox
存在与TVirtualStringTree
被删除的过程相同,我建议您专注于just CF_VTREFERENCE
,因为它是一种非常小而简单的格式(请参阅该TBaseVirtualTree.GetTreeFromDataObject()
方法的实现),而解析CF_VIRTUALTREE
数据将是过大的(请参见的实现)。该TBaseVirtualTree.ProcessOLEData()
方法)时,你可以通过源枚举TVirtualStringTree
,而不是直接。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句