一步一步教你实现CTreeCtrl 自绘( 四 )


函数的主要思路首先通过();获取第一个可见的节点,如果节点存在则按照我们的绘制顺序绘制,然后调用获得下一个可见的节点,一直循环,直到下一个可见节点为NULL的时候退出绘制函数 。
下面讲一下获取项热点的方法 。同样我们需要重写消息,这次是消息 。
我们首先定义一个数据来记录当前鼠标移动到的节点的句柄 。具体看代码 。
HTREEITEMm_MouseMoveItem;//鼠标移动到的项void CMyCtreeCtrl::OnMouseMove(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值m_ptOldMouse = point;HTREEITEM hItem = HitTest(point);if ( hItem != NULL && hItem != m_MouseMoveItem ){m_MouseMoveItem = hItem;Invalidate(FALSE);}//CTreeCtrl::OnMouseMove(nFlags, point);}接下来我们通过获取当前绘制的节点和m_MouseMoveItem比对,如果相同则设置当前的背景颜色,从而实现热点时间//绘制鼠标热点if (currentItem==m_MouseMoveItem&&ItemHasChildren(currentItem)==NULL){m_Gdiplus.usFillRectangle(pDc->m_hDC,fillRect,0xB7F0FE,0xB7F0FE,edoVertical,true);}//通过获取当前状态来判断单击事件 。if(itemState&TVIS_SELECTED){m_Gdiplus.usFillRectangle(pDc->m_hDC,fillRect,0xFF00BB,0xFF00BB,edoVertical,true);}这2句代码都在DrawItem函数中 。

之后在我们的一些常见操作之后触发就可以了 。
这种重写消息实现自绘的方法就是这些了,有没有觉得比我们前面的那种方法要简单好理解一些了 。下面说说我为什么选择这种方法而不用上面一种方法的原因,首先可以获取到树形控件的整个DC,感觉绘制的时候方便一些,我想绘制到什么地方就绘制到什么地方,容易控制 。其次是这种方法需要掌握的数据结构比较的少就需要知道几个常见的函数就OK了 。
需要掌握的函数:
::
( );
返回值:如果成功则返回第一个可视项的句柄;否则返回NULL 。
说明:
此成员函数用来获取该tree view控件中的第一个可视项的句柄 。
::
(hItem );
返回值:返回下一个可视项的句柄;否则返回NULL 。
参数:
hItem
一个tree项的句柄 。
说明:此成员函数用来获取hItem的下一个可视项 。
::
BOOL (hItem );
返回值:
如果由hItem指定的tree项有子项则返回非零值;否则返回0 。
参数:
hItem
一个tree项的句柄 。
::
(hItem ) const;
返回值:返回一个包含该项的文本的对象 。
参数:
hItem
要获取其文本的项的句柄 。
说明:
此成员函数返回由hItem指定的项的文本 。
::
BOOL (hItem,, BOOL);
返回值:
如果项是可视的则返回非零值,以及包含在中的边界矩形 。否则,返回0和没有被初始化的 。
参数:
hItem
一个tree view项的句柄 。
指向一个用来接收边界矩形的RECT结构的指针 。其中的坐标是相对于该tree view控件的左上角的 。
【一步一步教你实现CTreeCtrl 自绘】如果这个参数是非零值,则边界矩形值包括项的文本 。否则,它包括该项在tree view控件所占据的整个一行 。