当DragType
设置为dtOLE
(不是)时,是否可以将节点从
)TVirtualStringTree
拖放到VCL控件中dtVCL
我遇到一种情况,我需要能够将节点从一个 VT 拖动到另一个 VT(dtOLE
工作正常),但同时,在拖动时,我需要一个选项能够将节点放入 TListBox
(或其他 VCL 控件)中。
我尝试为 TListBox
句柄设置 DragAcceptFiles()
API,但没有效果。
如何做到这一点?
最佳答案
没有DragAcceptFiles
属性 TListBox
。如果你的意思是你正在调用Win32 API DragAcceptFiles()
TListBox.Handle
上的函数窗口,只有在以下情况下才有效:
您手动对
TListBox.WindowProc
进行子类化属性来处理WM_DROPFILES
窗口消息。TVirtualStringTree
提供CF_HDROP
OLE 拖动期间的格式。
2 并不正确。 CF_HDROP
仅用于拖动文件系统路径,这不是TVirtualStringTree
拖累。所以使用DragAcceptFiles()
已经出来了。
TVirtualStringTree
(以及其他TBaseVirtualTree
后代)在OLE拖动期间使用自定义数据格式(VirtualTrees.pas
单元的界面部分声明了这些格式ID,因此您不需要在自己的代码中手动注册它们):
CF_VIRTUALTREE
包含IStream
或HGLOBAL
保存正在拖动的选定树节点的序列化形式。序列化由一系列描述每个节点的数据 block 组成。您将不得不引用VirtualTree.pas
的实现单位来破译这种格式(我不打算在这里这样做)。CF_VTREFERENCE
包含HGLOBAL
拿着TVTReference
包含指向实际VirtualTrees.pas
的指针的记录(也在TBaseVirtualTree
单元的接口(interface)部分中声明)被拖出的对象以及树所属进程的ID。
因此,为了让您能够将树节点拖放到 TListBox
上,您必须执行以下操作:
编写一个实现
IDropTarget
的类接口(interface)(或使用预先存在的实现,例如 Anders Melander's Drag&Drop suite )。使用
TListBox.Handle
注册该类窗口使用RegisterDragDrop()
.在您的
IDropTarget
中实现,可以查询提供的IDataObject
对于CF_VIRTUALTREE
和CF_VTREFERENCE
格式。如果成功,您的Drop()
方法将可以访问正在拖动的树节点数据,并将其复制到TListBox
根据需要。
假设您的TListBox
与 TVirtualStringTree
存在于同一进程中被拖出来,我建议只关注 CF_VTREFERENCE
,因为它是一种非常小且简单的格式(请参阅 TBaseVirtualTree.GetTreeFromDataObject()
方法的实现),并解析 CF_VIRTUALTREE
当您只能通过源 TBaseVirtualTree.ProcessOLEData()
进行枚举时,数据将是多余的(请参阅 TVirtualStringTree
方法的实现)直接代替。
关于delphi - 如何使用 DragType dtOLE 将节点从 TVirtualStringTree 拖放到 VCL 控件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41729240/