敬业的IT人 >> 编程开发 >> 其他语言 >> 控件“树”中多选拖放功能的实现

控件“树”中多选拖放功能的实现

敬业的IT人 互联网 佚名 2008-2-20 19:57:41

控件“树”中多选拖放功能的实现

 

发布日期: 2/14/2002 | 更新日期: 6/30/2004

控件”树”(tree)能够清晰地显示所包含数据的继承关系,是一个强有力的控件。但是真正掌握并能运用CTreeCtrl类的众多特性并不是一件容易的事情。在Visual C++Developer杂志的9月份、10月份这两期中,Stephen介绍了两个类CBitmapTree和CCheckableTree的用法,这两个类可以扩展和简化类CTreeCtrl。在这篇文章里,将主要介绍类CBitmapTree的升级版,它可以简化往”树”控件中添加拖放功能的过程,而且还可以实现多选拖放功能。

在CTreeCtrl类中,拖放特性是很难掌握和应用的特性之一。由于该特性能给拖放操作带来许多特有的灵活性,所以MFC组专门指派程序员负责这方面函数的编写工作,这将使得用户在开发的应用程序中实现控件”树”的拖放功能不再"望而生畏"。这里将介绍类CBitmapTree中扩充的有关成员函数,以便简化控件”树”的拖放功能的实现,同时还将该特性扩展到多选拖放。

本文所做的介绍是假定您已经对9、10月份Visual C++ Developer杂志中有关文章里面的概念和技术有所了解。这两篇文章的题目是 A Tree Cborder="0" alt="控件“树”中多选拖放功能的实现(图一)" />

可拖动的项和释放的目标位置(Draggable items and drop targets)

拖放操作主要包含两个行为对象:被拖动的项和释放的目标位置项。为了支持可反复进行的拖放操作功能,需要能够识别出树控件类中哪些项是可拖动的以及它们的释放位置如何,而不是去识别父窗口类中的项。通过一个成员变量m_draggable中某一特定位值的设置可以设置某项的拖动特性,就象一个树的图象可以设置成"可扩充"特性一样。函数SetDraggable()、IsDraggable()、SetDropTarget()和IsDropTarget()中就使用了该成员变量m_draggable。下面是函数SetDraggable()的代码:

void CBitmapTree::SetDraggable(int base)
{
ASSERT(base < (sizeof(m_draggable)*8 -1));
m_draggable|= (1UL << base);
}

熟悉类CBitmapTree的读者可能注意到了该函数与SetExpandable()函数极其相似。变量base指明了所选的图象在"树"控件TVISL_NORMAL图象列表中的索引号。该索引号将转换成一个单位值,并且存储在成员变量m_draggable中。m_draggable成员变量类型为长整型,占4个字节32位,所以变量base指定的是位于图象列表中前32个图象中的某一个图象。而成员函数IsDraggable()可以用来查询变量m_draggable的值。成员函数IsDraggable()和IsDropTarget()都定义为虚函数,所以在需要对可拖动特性和可释放特性进行更为复杂的判断时,用户可以在类CBitmapTree的派生类中超越(overriding)该函数。网址www.pinpub.com/vcd下Subscriber Downloads部分中所包含的程序示例中,所有的文档节点都是可拖动的,所有的文件夹节点都可以作为拖动后释放的目标位置项。

控件“树”中多选拖放功能的实现(图二)返回页首

准备拖动(Getting ready to drag)

当成功地执行完一次拖放操作后,函数SetDrag()就会建立一个回调函数来处理树项的移动或复制。笔者曾经在前面的文章里提供了一个比较简单的回调函数MoveTreeItemCB(),它可以完成树项在"树"控件中从一个位置移动到另一个位置。注意:这个函数本身的局限性很强,如果想完成某些该函数不具备的其它方面的功能时,就需要用户根据实际需要编写自己的回调函数。(例如,当使用宏LPSTR_TEXTCALLBACK来替代表示树项的文本时,函数MoveTreeItemCB()就不能正常运行。)

另外,在拖动树项时,可以提供给函数SetDrag()一个位图的资源标识符(并不是必需的)。该位图可以作为一种提示图标,它应该具有如图1所示的格式。当拖动超出了有效范围的边界时,则显示第一个图象;当拖动项只有一项时,则显示第二个图象;当拖动项包含多项时,则显示第三个图象。如果在程序中并没有提供图象给函数SetDrag(),那么将显示一个缺省的拖动图象,即当前所选项的灰色显示。

控件“树”中多选拖放功能的实现(图三)

返回页首

开始拖动(Beginning a drag)

拖动操作开始时,"树"控件的父窗口将接收到一个通知消息TVN_BEGINDRAG。您可以向CBitmapTree类的消息映象中发送一通知消息border="0" alt="控件“树”中多选拖放功能的实现(图二)" />返回页首

拖动控件"树"中的项(Dragging a tree item)

在执行拖动操作的过程中,拖动图象根据操作的不同,显示上也有些变化。下面的处理程序border="0" alt="控件“树”中多选拖放功能的实现(图四)" />

返回页首

边拖边滚

当拖动操作位于"树"控件的有效边界时,如果能够实现"树"控件窗口的自动上滚或下滚以显示其余的树项,那将是件很漂亮的工作。使用border="0" alt="控件“树”中多选拖放功能的实现(图二)" />返回页首

拖动结束(When the drag is over)

当释放鼠标左键时,拖动操作结束。下面的OnLButtonUp()消息处理函数可以完成拖动结束时的各种事后处理工作:

void CBitmapTree::OnLButtonUp(UINT nFlags, 
CPoint point) 
{
if (m_dragList)
{
进入讨论组讨论。
	
粤ICP备06119539号
Copyright CiscoSky.Org,Some Rights Reserved.
Email:me1228#tom.com