【wxWidgets】剪贴板和拖放操作
使用剪贴板传输数据时应用程序间的一种交互方式
剪贴板和拖放操作在wxWidgets中共享了一些类来实现数据的传输
数据对象
wxDataObject类时剪贴板操作和拖放操作的核心,该类实例代表了拖放操作中鼠标拖拽的事物和剪贴板中拷贝和粘贴的事物
通过GetFormatCount函数和GetAllFormats函数能知道可支持的格式
实现SetData函数可以从外部接受不同格式的数据
wxDataFormate标准的数据格式:
数据源的职责
数据源负责创建要传输的数据对象,创建对象后通过SetData函数将其传递给剪贴板,或者在拖放操作中用DoDragDrop函数将其传递给一个wxDropSource对象
剪贴和拖放最大的不同:
- 剪贴板传输数据需要使用new在堆上创建对象,在其不被需要时释放
- 拖放数据对象只需要在DoDragDrop执行期间存在,执行结束即可释放
数据目标的职责
要接收数据应该先创建一个想要的数据格式wxDataObject的派生类,以便传递给wxClipboard::GetData函数,返回失败则剪贴板上没有目标类型数据
使用剪贴板
剪贴板主要调用wxTheClipboard的成员函数,在进行拷贝和粘贴之前先通过wxClipborad::Open获得剪贴板的控制权,调用wxClipboard::SetData来将数据拷贝到剪贴板上,或者调用wxClipboard::GetData获取数据,最后调用wxClipboard::Close释放控制权
wxClipboardLocker类可以在其构造函数获得剪贴板的控制权,在其析构函数释放剪贴板控制权
下面演示剪贴板上的文本操作:
下面演示剪贴板上的图片操作:
使用剪贴板可能需要及时更新界面,通过wxWidgets界面更新机制来完成,向程序发送wxUpdateUIEvent事件,在系统空闲的时候根据剪贴板的数据更新界面
在某些控件比如wxTextCtrl已经实现了自动更新
实现拖放操作
实现拖放源
提供用户用于拖放操作的数据需要使用一个wxDropSource类实例
一个拖放源需要采取的动作包括下面几步:
- 准备工作:先创建和初始化一个将被拖动的数据对象
- 开始拖动:最典型的方式是相应鼠标单击事件,创建一个wxDropSource对象,调用wxDropSource::DoDragDrop函数
以下为DoDragDrop函数参数
当创建wxDropSource对象可以指定发起拖动操作的窗口,可以选择拖动使用的光标,可选范围包括拷贝,移动以及不能释放等,这些光标在GTK+上是图标,而在别的平台上是光标,因此需要hi使用wxDROP_ICON来屏蔽这种区别 - 拖动过程:对DoDragDrop函数的调用将会阻止应用程序进行其他处理,直到用户释放鼠标按钮(除非重载了GiveFeedback函数以便实现其他特殊操作)当鼠标在应用程序的窗口上移动时,如果这个窗口可以识别这个拖动操作协议,对应的wxDropTarget函数就会被调用
- 处理拖放结果:DoDragDrop函数返回一个拖放操作的结果,返回值类型为wxDragResult,枚举值如下
程序可以针对不同的返回值进行操作,如果返回值是wxDragMove,通常需要删除绑定在数据源中的数据,然后更新屏幕显示。而如果返回值wxDragNone,则表示拖动操作已经被取消了
下面演示了实现一个文本数据拖放源,DnDWindow包含一个m_strText成员变量,当鼠标左键按下时,针对m_strText拖放操作开始,拖放操作的结果通过一个消息框显示,另外拖放操作将会在鼠标已经拖动了一小段距离后才会开始,因此单机鼠标动作并不会导致一个拖放操作
实现一个拖放目的
要实现拖放目的,接受用户拖动的数据,需要使用wxWindow::SetDropTarget函数,将某个窗口和一个wxDropTarget绑定在一起,需要实现一个wxDropTarget的派生类,并且重载虚函数
还需要重载OnDragOver函数,以便返回一个wxDragResult类型的返回码,以说明当鼠标指针移过窗口时光标怎样显示,并且重载OnData函数来实现放置操作,可以通过继承wxTexTDropTarget或者wxFileDropTarget,或者重载它们的OnDropText或者OnDropFiles函数来实现拖放
- 初始化:wxWindow::SetDropTarget函数在窗口创建期间被调用,以便将其和一个拖放目的对象绑定,在窗口创建或者应用程序的其他某个部分,通过函数wxDropTarget::SetDataObject,拖放目的对象和某一种数据类型绑定,这种数据类型将用来作为拖放源和播放目的进行协商的依据
- 拖动:当鼠标在拖放目的上以拖动的方式移动时,wxDropTarget::OnEnter,wxDropTarget::OnDragOver和wxDroptarget::OnLeave函数将在适当的时候被调用,它们都将返回一个对应的wxDragResult值,以便施放操作可以对其进行合适的用户界面反馈
- 放置:当用户释放鼠标按钮的时候,wxWidgets通过调用函数wxDataObject::GetALLFormats询问窗口绑定的wxDropTarget对象是否接受正在拖动的数据,如果数据类型是可接受的,那么wxDropTarget::OnData将被调用。拖放对象绑定的wxDataObject对象将进行对应的数据填充动作,wxDropTarget::OnData函数将返回一个wxDragResult类型的值,作为wxDropSource::DoDragDrop函数的返回值
使用标准的拖放目的对象
to be continued…