• TvirtualStringTree之DragDrop


         昨天在项目中需要做一个播放列表管理界面,播放列表中的结点本身要求可以拖动,并且要求播放列表能够支持从资源管理器上拖入FLV文件和播放列表文件。我继续使用了强大的TvirtualStringTree组件,但是在同时支持这两种拖动上犯了难,以前做的程序都是只支持其中一种拖动。

       将TvirtualStringTree组件的dragMode属性设置为dmAutomatic,然后添加onDragOver事件,在事件处理函数中将Accept设置为true,然后运行,嗯很好,结点已经可以拖动了,而且拖动到结点的不同位置,光标处加亮形式是不一样的,也就是可以分别拖到结点正上方、和结点上面、和结点下面,做到这里我就知道结点是已经可以拖动的了。

      然后开始处理文件的拖动,嗯,现成的有个TargetFileDrop组件,好的,拖到界面上去,目标设置为我使用的TvirtualStringTree组件,然后运行。砰……程序挂掉,弹出错误提示:“该窗口已经被注册为了拖放目标”。哇靠,不让我两个一起使用,我郁闷。然后仔细看看这个错误是OleException的一种,心里想我啥时候将TvirtualStringTree组件也注册为ole拖动对象了?看看TvirtualStringTree组件的属性,嗯,看见了属性TreeOptions.MiscOptions.toAcceptOleDrop默认是为true,原来是这个属性,想都不想直接改为false,然后运行。嗯,很好程序没挂。拖一个FLV到组件上面,等等,怎么拖动到指定结点,把鼠标移到任何地方都不加亮,这可真郁闷,因为我拖入文件要能够拖到指定的播放列表上去的。看来TargetFileDrop组件不合要求,pass。然后试一下拖动结点,唉?怎么也没加亮了?难道,难道是?对了,是TreeOptions.MiscOptions.toAcceptOleDrop属性的问题,还是改回true吧。嗯,可以有加亮了。

       继续寻找拖入文件的方法,百度一下,嗯,有个方法是要将组件使用AcceptFileDrop函数注册成为能够接收文件拖放的组件?好方法,那来吧,照着说明添加上代码,然后运行,怎么发现怎么都执行不到消息处理代码里去,都直接执行到组件的OnDragDrop事件里了。唉,使用消息添加文件的方法,又失败……

       继续看,嗯VB的Ole拖放?有么有delphi版本的?没有。没有怎么办,不管了,继续找。嗯,等等,ole拖放?怎么这么熟悉,向上看看toAcceptOleDrop属性,哇这个组件已经支持ole拖放了,看来还是去研究研究TvirtualStringTree的帮助文件吧。找到OnDragDrop事件的帮助文档,讲的不多,但是提到了

    1. If you do not find CF_VIRTUALTREE then the operation has been initiated by another application, e.g. the Explorer (then you will find CF_HDROP or CF_SHELLIDLIST in formats) or Notepad (then you will get CF_TEXT and perhaps CF_UNICODETEXT) etc., depending on the data which is actually dropped.

    嗯,看来是可以响应拖入文件的,而且帮助文件里还给了一个示范的代码(郁闷的是这个示范代码只处理 CF_VIRTUALTREE,其它的都没有),那照着搬一下。

    运行然后拖入文件,嗯有提示了,证明是能够执行到ShowMessage的地方,但是从哪里去找拖入的文件名呢?看参数说明,是可以从DataObject里找到数据,但是鬼知道怎么获取数据啊,百度没有,google没有,唉,看TDropFIletarget自己的源码是怎么处理DataOjbect的,从上面的代码看到DataObject参数传给方法ProcessDrop再传到GetTreeFromDataObject,然后,嗯,有处理代码了。

    嗯,照着做吧,但问题只有一个对应着cfFormat = CF_HDROP的数据是什么格式?对GlobaLock返回的指针我怎么处理。结果没有一个地方有说明,MSDN、delphi的Windows SDK帮助文档上对CF_HDROP都没有说明,使用百度对CF_HDROP进行搜索,发现只有对剪切板的一些操作的示范代码,再回去研究下OleDrop的原理,正是将数据存到剪切板中。那么,把对剪切板的操作的代码移植到程序中,好了,一个成功的OnDragDrop事件处理函数出来了。

    然后运行,拖入一个文件,OK,文件全路径弹出来了。搞定了这一步,下面的就是一个程序逻辑问题了,嘿嘿。

  • 相关阅读:
    fatal: protocol error: bad line length character: This
    httpd: apr_sockaddr_info_get() failed for bogon
    Go语言函数
    Go语言流程控制
    进制转换
    Go语言运算符
    LeetCode 62. Unique Paths
    LeetCode 61. Rotate List
    asdfasdfasdf
    开发者,别让自己孤独
  • 原文地址:https://www.cnblogs.com/k1988/p/2165736.html
Copyright © 2020-2023  润新知