分隔视图与TreeView都是在界面中常用的元素,本文介绍了如果使用这两种元素,并说明了TreeView的显示与控制方法.如:如何使TreeView响应鼠标的单,双击,右击等事件.
首先说明如何分隔一个窗口.
在MFC中,分隔一个窗口,这个窗口必须是CWnd或其派生类.这里面以CFrameWnd为例.其它的也一样.
现在假如有一个类: class CMainFrame : public CframeWnn,我们在它的头文件中加入:
CSplitterWnd m_wndSplitter;
然后重载它的OnCreateClient函数.
在里面加入如下代码:
if(!m_wndSplitter.CreateStatic(this,1,2))
{
return FALSE;
}
if(!m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CMainView),size,pContext))
return FALSE;
if(!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CRoomsTree),size,pContext))
return FALSE;
(CMainView*)m_pView = (CMainView*)m_wndSplitter.GetPane(0,1);
(CRoomsTree*)m_pTree = (CRoomsTree*)m_wndSplitter.GetPane(0,0);
其中, CreateStatic函数的原型可以查下MSDN,利用它就可以做出各种不同的分隔效果.
上面代码中的CMainView和CRoomsTree都是视类的派生类.而CreatView函数也是可以查下MSDN,里面有具体的说明.
那么如何得到这两个类的指针呢?
(CMainView*)m_pView = (CMainView*)m_wndSplitter.GetPane(0,1);
(CRoomsTree*)m_pTree = (CRoomsTree*)m_wndSplitter.GetPane(0,0);
这两句就可以了.
下面运行程序,就可以看到效果了.
下面讲如果制作树视图(控件).
就拿上面的例子来说,我们在它的基础上加入一个树控件.
生成一个新类,就是上面的CRoomsTree,它的基类是CTreeView,在它的头文件中加入:
CTreeCtrl & m_Tree;
然后在构造函数中初始化它:
CRoomsTree::CRoomsTree():m_Tree(GetTreeCtrl())
这里是调用的它的考备构造函数,具体的找本C++的书看就行了.
下面讲如何给树的项目制作图标.
在其头文件中加入: CImageList m_ImageList ;
然后在需要显示树的时候(一般是OnCreate函数中):
m_ImageList.Create(IDB_TREEIMAGE,16,1,RGB(255,0,255));
这里面IDB_TREEIMAGE是一张位图在资源中的ID,这张位图要你自己画.
然后加上这句就把位图加到树上面了:
m_Tree.SetImageList(&m_ImageList,TVSIL_NORMAL);
下面讲如何给树插入项目:
用m_Tree.InsertItem,
这个函数的返回值是一个项目的句柄,参数有四个,1.项目的文字,2.项目被选中时要显示的图标在ImageList中的位置,3.项目没选中时的图标.4.该项目父项目的句柄,如果为NULL,该项目就显示在根位置.
好了,现在,随便插入几个项目,运行程序,就可以看到效果了.
那么,我们如何控制这个树呢?如何让它响应我们的操作?
就拿单击来说吧
响应它的: NM_CLICK消息,在消息回调中加入:
GetCursorPos(&m_CurrentPnt);
ScreenToClient(&m_CurrentPnt);
m_CurrentItem = m_Tree.GetSelectedItem();
*pResult = 0;
用这种方法得到单击时鼠标的位置,和当前被选择的项目的句柄,然后用:
CRect rect;
m_Tree.GetItemRect(m_AllItem,&rect,TRUE);
if (rect.PtInRect(m_CurrentPnt))
{
//
}
来看是不是点击了其中之一就可以了.
如果想知道到底是点击的哪个项目,就要用上面的办法把所有的项目检查一遍
这样,就差不多了.双击也是一样的.
在实际的操作中,会出现一个问题,就是双击的时候,它会触发单击和双击两个事件.
这怎么办呢?
我用的办法是,在类中设一开关变量,
单检查到有单击事件时,开关打开,并SetTimer,一般为500ms,然后,在双击事件中,关闭开关,在Timer的响应函数中,先检查开关是否打开,如果打开,再做相应的单击后的处理就可以了.