我在把asc转换为UNICODE过程中,发现树控件的消息触发略有些不同
TVN_ITEMEXPANDING 和 TVN_ITEMEXPANDED 消息 在节点第一次调用Expand时触发 ,触发后,为该节点设置TVIS_EXPANDEDONCE 状态
但是,在实验中我发现,UNICODE环境下,SelectItem(htree) 也会触发该消息,而在ASC环境中,SelectItem则不会触发
而且:
在UNICODE环境中,要收缩某节点时,必须先用SelectItem选择改节点后,才能收缩
在ASC环境中,第一次调用Expand时,首先触发消息TVN_ITEMEXPANDING 和 TVN_ITEMEXPANDED 消息,然后设置TVIS_EXPANDEDONCE 状态,最后扩展根据参数扩展或收缩改节点
在UNICODE环境中,第一次调用Expand时,首先触发消息TVN_ITEMEXPANDING 和 TVN_ITEMEXPANDED 消息,然后设置TVIS_EXPANDEDONCE 状态,但是到此为止了。他并不扩展或收缩改节点,而是必须再次调用Expand才可以
不知道,是不是VS2005的BUG所致,还是什么其他原因,实在是奇怪
ASC环境下代码:
void CLeftView::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult) { // TODO: 在此添加控件通知处理程序代码 CshowImageDoc *pDoc=GetDocument(); CPoint pt; pt=GetCurrentMessage()->pt; GetTreeCtrl().ScreenToClient(&pt); UINT uFlag = 0; HTREEITEM hCurSel = GetTreeCtrl().GetSelectedItem(); HTREEITEM hItem = GetTreeCtrl().HitTest(pt, &uFlag); if(hItem) { if(hCurSel != hItem) { GetTreeCtrl().SelectItem(hItem); } GetTreeCtrl().Expand(hItem,TVE_TOGGLE); pDoc->ModifyIcon(hItem); } }
unicode环境下的代码
void CUnicodeTree::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult) { // TODO: 在此添加控件通知处理程序代码 *pResult = 0; CMagazineEditDoc *pDoc=GetDocument(); CPoint pt; pt=GetCurrentMessage()->pt; GetTreeCtrl().ScreenToClient(&pt); UINT uFlag = 0; HTREEITEM hCurSel = GetTreeCtrl().GetSelectedItem(); HTREEITEM hItem = GetTreeCtrl().HitTest(pt, &uFlag); if(hItem) { if ((GetTreeCtrl().GetItemState(hItem,TVIS_EXPANDEDONCE )&TVIS_EXPANDEDONCE )!=0 ) //判断是否扩展过一次,若是直接调用EXPAND { GetTreeCtrl().SelectItem(hItem); //收缩节点时,必须先选择改节点 GetTreeCtrl().Expand(hItem,TVE_TOGGLE); } else{ // 若该节点还未扩展过,首先利用第一个Expand触发TvnItemexpanding消息,然后利用第二个Expand将其扩展 GetTreeCtrl().Expand(hItem,TVE_TOGGLE); GetTreeCtrl().Expand(hItem,TVE_TOGGLE); } if(hCurSel != hItem) { GetTreeCtrl().SelectItem(hItem); //将选择放在最后 ,否则 若是第一次展开时, 遇到选择SelectItem 也会触发TvnItemexpanding消息 } pDoc->ModifyIcon(hItem); } }
注: 原来理解错了 , 两者并没有不同
而是,我将自己的程序加到别人的程序中时出现的问题
现在才发现错误原因: 别人的程序响应了OnTvnSelchanged 消息 ,而且那个消息处理函数中调用了 ctrl.Expand(hParentItem,TVE_EXPAND);
,一开始没注意,害得我还以为是两者环境下 CTreeCtrl运行机制不同呢