11.1 数据对象

wxDataObject类是剪贴板操作和拖放操作的核心,这个类的实例代表了拖放操作中鼠标拖拽的事物,以及剪贴板操作中拷贝和粘贴的事物. wxDataObject是一块聪明的数据,因为它知道哪种格式它可以支持(通过GetFormatCount和GetAllFormats),也知道怎样来支持它们(通过GetdataHere).如果实现了对应的SetData函数,它也可以从应用程序的外部接受不同格式的数据.我们将在本章的后边对此进行介绍.

标准的数据格式,比如wxDF_TEXT是用整数来区分的,而定制的数据格式则是通过字符串来区分的.wxDataFormat类支持使用这两种参数的构造函数.下表列出了标准的数据格式.

wxDF_INVALID 无效格式,用于缺省的wxDataFormat的构造函数.
wxDF_TEXT 文本数据格式,对应的数据类型为wxTexTDataObject.
wxDF_BITMAP 图片数据格式,对应的数据类型为wxBitmapDataObject.
wxDF_METAFILE 元文件数据格式,对应的数据类型为wxMetafileDataObject(仅支持Windows)
wxDF_FILENAME 文件名列表数据格式,对应的数据类型为wxFileDataObject.

你也可以创建定制的数据格式,在这种情况下,你需要给wxDataFormat构造函数传递一个定制的字符串,来标识你的定制的数据类型,这个数据类型将在首次使用的时候被登记.

剪贴板操作和拖放操作都需要处理数据源(数据提供者)和数据目标(数据接收者).它们可以位于同一个应用程序内,甚至是位于同一个窗口内,比如,你在同一个窗口内把一段文本从一个位置拖到另一个位置,我们来分别描述一下这两个角色.

数据源的职责

数据源负责创建要包含要传输的数据的数据对象,在创建数据对象以后,数据源还负责通过SetData函数将其传递给剪贴板,或者在拖放操作开始时,通过DoDragDrop函数将其传递给一个wxDropSource对象.

在这种情况下,剪贴板操作和拖放操作的最大的不同在于剪贴板传输的数据必须使用new函数,在堆上创建,而且只能被剪贴板在其不被需要的时候释放,事实上,我们根本不知道它是在什么时候被释放的,我们甚至连原始的数据是什么时候被放到剪贴板上去的也不知道.而另一方面,用于拖放操作的数据对象只需要在DoDragDrop执行期间存在,执行完以后就可以被安全地释放了,因此,这种数据对象,即可以在堆上创建,也可以在栈上创建(意思就是一个局部变量).

另一个细微的差别在于:对于剪贴板操作应用程序通常很清楚它正在进行的操作的整个过程.当进行了剪切操作的时候,数据被首先拷贝到剪切板,然后从当前操作的对象中移除.这通常是由于用户对菜单项的选择来触发的.但是对于拖放操作来说,应用程序只有在DoDragDrop函数执行以后,才能了解这些信息.

数据目标的职责

要从剪贴板接收数据(意味着一个粘贴操作),你应该首先创建一个支持你想要获取的数据格式的wxDataObject的派生类,以便将其传递给wxClipboard::GetData函数.如果这个函数返回失败,表明剪贴板上没有你想要的类型的数据.如果返回成功,则表明剪贴板上的数据已经被成功地传输到你创建的wxDataObject的派生类中.

对于拖放操作,当一个数据对象被放置的时候,wxDropTarget::OnData虚函数将会被调用.如果数据类型合适,应用程序可以调用wxDropTarget::OnData函数来获取相应的数据.