深度理解:CTreeCtrl展开和收起消息探究

在使用树控件(CTreeCtrl)的过程中,有时候需要捕获树结点的展开(Expand)和收起(Collapse)事件并做一些自定义的操作。

今天就来探究一下树结点的展开和收起这两种消息,我们使用到了微软开发的小工具Control Spy,这个工具可以捕获Windows平台上各个控件的消息流。

深度理解:CTreeCtrl展开和收起消息探究_第1张图片

TVN_ITEMEXPANDING和TVN_ITEMEXPANDED消息的触发

每当树控件展开之前,树控件会向其父窗口发送TVN_ITEMEXPANDING通知,表示:我要开始展开结点啦,你同意吗?

如果父窗口允许结点展开,则树控件会展开结点,等展开结点这一动作完成之后,会向父窗口发送TVN_ITEMEXPANDED,表示:树结点展开已经完成。

我们在使用树控件的过程中,可以使用如下几种方式触发TVN_ITEMEXPANDING和TVN_ITEMEXPANDED消息:

1) 双击树控件的文字部分。

2) 单击树控件加减号。

3) 当树结点被选中时,点击键盘的向左(结点收起)或向右(结点展开)的箭头按键。

好,我们来分别看看这几个动作下,控件发送的消息。

双击树控件的文字部分

当我们双击树控件的文字部分时,树控件展开。它会首先发送NM_DBLCLK,然后发送TVN_ITEMEXPANDING,最后发送TVN_ITEMEXPANDED。

深度理解:CTreeCtrl展开和收起消息探究_第2张图片

树控件展开后,再次双击树控件的文字部分,树控件收起。其消息发送流程和展开时的一致。

单击树控件加减号

当我们单击树控件前面的加减号时,树控件也会相应的展开或收起。具体来说,点击加号会展开树结点,结点展开后,加号会变成减号。当点击减号时,树结点会收起,结点收起后,减号会变成加号。

深度理解:CTreeCtrl展开和收起消息探究_第3张图片

注意,和上面双击操作不同的是,这里单击加减号,首先发送的NM_CLICK,而不是NM_DBLCLK。

另外需要注意的是:树控件的展开或收起动作是当加减号被鼠标按下就被触发的,而不是鼠标弹起的时候。所以,我们会感受到,鼠标还没有弹起,树结点就已经开始动作了。

按下键盘左右箭头

当一个树结点处于选中状态,我们也可以通过按下键盘上的向左向右箭头实现树控件的展开或收起。

深度理解:CTreeCtrl展开和收起消息探究_第4张图片

注意,这里首先发送的是TVN_KEYDOWN,表示键盘上的箭头按键被按下,然后才是发送TVN_ITEMEXPANDING和TVN_ITEMEXPANDED消息。

和上述单击加减号操作一样,树结点展开或收起是在键盘被按下的时候触发,而不是弹起的时候。

好了,消息流已经弄清楚了,可以开始编写一些相应的代码了。在MFC中,我们可以方便的通过类向导完成TVN_ITEMEXPANDING和TVN_ITEMEXPANDED消息的处理。

通过在父窗口中添加ON_NOTIFY宏,实现消息的映射

TVN_ITEMEXPANDING消息的处理:树控件展开或收起动作开始执行之前被发送给父窗口,父窗口可以在这里中止操作

深度理解:CTreeCtrl展开和收起消息探究_第5张图片

TVN_ITEMEXPANDED消息的处理:树结点完成展开或收起操作之后,会向父窗口发送此通知,因结点动作已经完成,父窗口对结点的展开或收起的控制已经无能为力了。

深度理解:CTreeCtrl展开和收起消息探究_第6张图片

总结

基本上理清了树结点展开或收起的消息流程,这里要吐槽的一点是:当通过点击加减号实现树结点的展开或收起时,系统默认实现是当鼠标按下时就触发,我认为一个重视用户体验的程序,应该设计为当鼠标被弹起的时候才触发。

如果想实现这一点,只能对树控件进行自绘了。那就是另一个话题了,今天就不在这里讲解了。

你可能感兴趣的:(深度理解:CTreeCtrl展开和收起消息探究)