2007年5月26日土曜日

树控件的创建

MSDN上说,在MFC中树控件有三种创建方法:

1. 在对话框模版中添加一个TreeBox控件(假设其ID 为:IDR_TREE), 则自动生成一个树控件对象。通过在对话框类中的OnInitDlg()函数中, 使用CTreeCtrl *pTree = (CTreeCtrl *) GetDlgItem(IDR_TREE); 将得到CTreeCtrl对象的指针, 使用此指针就可以对树控件进行操作。

另外, 对树控件的消息以及消息处理函数都是在对话框类中添加。

2. 使用CTreeView。 这样AppWzard将自动创建一个相关的CTreeCtrl 对象。

3. 使用CTreeCtrl::Create()函数创建。



void CTreeCtrl::Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID )



其中dwStyle使用以下树控件专用的风格:

TVS_HASLINES 在父/子结点之间绘制连线

TVS_LINESATROOT 在根/子结点之间绘制连线

TVS_HASBUTTONS 在每一个结点前添加一个按钮,用于表示当前结点是否已被展开

TVS_EDITLABELS 结点的显示字符可以被编辑

TVS_SHOWSELALWAYS 在失去焦点时也显示当前选中的结点

TVS_DISABLEDRAGDROP 不允许Drag/Drop

TVS_NOTOOLTIPS 不使用ToolTip显示结点的显示字符

TVS_CHECKBOXES 在每项旁边添加一个选择框



此外, dwStyle在树控件创建时一定要加上WS_VISIBLE , 否则树控件将会被隐藏!!当然,如果没有加上这个WS_VISIBLE也可以在创建之后立即调用ShowWindow(SW_SHOWNORMAL),控件便显示出来了,若调用ShowWindow(SW_HIDE)控件便隐藏了。同时,一般情况下,树控件是作为子窗口使用,那么在创建时要加上WS_CHILD,表示控件是子窗口(那么在创建时当然要指定父窗口了)。

nID可以随便定义一个和其他ID值不冲突的数字便于标识(当然也可以直接用数字,这里用的是IDD_TREE)。 而pParentWnd则指向树控件的父窗口, 在对话框中是对话框类对象的指针, 在视图中, 是视图类对象的指针(这里使用的是this指针)。 我在视图类CScrollView中的OninitialUpdate()函数中加入一个树控件:

m_tree.Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER

| TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES

| TVS_DISABLEDRAGDROP, CRect(0,0,100,100),this,IDD_TREE);



HTREEITEM hItem,hSubItem;



hItem = m_tree.InsertItem(_T("Parent1"),TVI_ROOT);

//在根结点上添加Parent1



hSubItem = m_tree.InsertItem(_T("Child1_1"),hItem);

//在Parent1上添加一个子结点



hSubItem = m_tree.InsertItem(_T("Child1_2"),hItem,hSubItem);

//在Parent1上添加一个子结点,排在Child1_1后面



hSubItem = m_tree.InsertItem(_T("Child1_3"),hItem,hSubItem);



hItem = m_tree.InsertItem(_T("Parent2"),TVI_ROOT,hItem);

hItem = m_tree.InsertItem(_T("Parent3"),TVI_ROOT,hItem);



其中的m_tree在CMyScrollView头文件中声明为:

Private:

CTreeCtrl m_tree;





注意: 一定要在头文件中声明一个树控件类的对象, 不能在函数中声明(表示对象是临时的), 如果在函数中声明了类对象, 那么在函数返回后该对象会被消除, 这样就无法显示树控件了!!!



父窗口指定为this指针,即CMyScrollView指针,表示树控件将会向它发送命令消息(WM_COMMAND)和通知消息(WM_NOTIFY)。那么所有的树控件处理消息都将在这个父窗口进行处理。(在对话框中的情形相同)

例如:为了能对树控件进行操作, 必须添加消息和消息处理函数。 此时由于是用Create()函数创建的树控件, 无法用AppWzard 为它产生消息以及消息处理函数, 必须手动添加。

例如:在CMyScrollView的头文件中声明: (用于处理双击树控件项事件)



afx_msg void OnTreeDblClk(NMHDR * pNMHDR, LRESULT *pResult);



在CMyScrollView的实现文件中添加:

BEGIN_MESSAGE_MAP(CMyScrollView, CScrollView)

…。

…。

ON_NOTIFY(NM_DBLCLK, IDD_TREE, OnTreeDblClk)

…。

…。

END_MESSAGE_MAP()



void CMyScrollView::OnTreeDblClk(NMHDR* pNMHDR, LRESULT *pResult)

{

HTREEITEM hSelected = m_tree.GetSelectedItem();

if (hSelected != NULL) {



if(m_tree.GetItemText(hSelected) == "Child1_1"){

AfxMessageBox(_T("This Child1_1 is Clicked!"));

}



}



*pResult = 0;

}

0 件のコメント: