MFC VC 中 TreeView 全面解析Word文档格式.docx
《MFC VC 中 TreeView 全面解析Word文档格式.docx》由会员分享,可在线阅读,更多相关《MFC VC 中 TreeView 全面解析Word文档格式.docx(10页珍藏版)》请在冰豆网上搜索。
rect,CWnd*pParentWnd,UINTnID);
其中参数dwStyle用来确定树控制的类型;
rect用来确定树控制的大小和位置;
pParentWnd用来确定树控制的父窗口,通用是一个对话框并且不能为NULL;
nID用来确定树控制的标识。
树控制的风格可以是下列值的组合:
TVS_HASLINES表示树控制在各子项之间存在连线;
TVS_LINESATROOT表示树控制在根项之间存在连线;
TVS_HASBUTTONS表示树控制视在父项左侧存在展开合拢控制按钮;
TVS_EDITLABELS表示可以控制鼠标单击修改树项的名称;
TVS_SHOWSELALWAYS表示选中项即使在窗口失去输入焦点时仍然保持选中状态;
TVS_DISABLEDRAGDROP表示禁止树控制发送TVN_BEGINDRAG消息
2、树控制的属性类
树控制属性类包括取得树控制中项数GetCount、取得树控制中项相对于父项的偏移值GetIndent、取得树控制图像列表控制句柄GetImageList、设置树控制图像列表控制句柄SetImageList、取得匹配下一个树项GetNextItem、判断给定树项是否包含子项ItemHasChildren、取得树项子项GetChildItem、取得下一个同属树项GetNextSiblingItem、取得前一个同属树项GetPrevSiblingItem、取得父树项GetParentItem、取得第一个可视树项GetFirstVisibleItem、取得下一个可视树项GetNextVisibleItem、取得前一个可视的树项GetPrevVisibleItem、取得被选中的树项GetSelectedItem、取得根树项GetRootItem、取得树项的属性GetItem、设置树项的属性SetItem、取得树项的状态GetItemState、设置树项的状态SetItemState、取得与树项关联图像GetItemImage、设置与树项关联图像SetItemImage、取得树项文本GetItemText、设置树项文本SetItemText和取得树项编辑控制句柄GetEditControl等。
3、树控制的操作方法
树控制的操作方法包括插入一个树项InsertItem、删除一个树项DeleteItem、删除所有树项DeleteAllItems、展开或合拢树项的子项Expand、选中特定树项SelectItem、选择一个树项作为第一个可视树项SelectSetFirstVisible、编辑一个可视的树项EditLabel和排序给定父树项的子树项SortChildren等。
(三)树控制的数据结构
在使用树控制时需要了解两个个非常重要的数据结构TV_ITEM和TV_INSERTSTRUCT,前一个数据结构是用来表示树控制的树项信息,后一个数据结构是用来定义将树项增加到数据控制中所需要的数据内容。
另外,还需要NM_TREEVIEW、TV_DISPINFO和TV_HITTESTINFO三个数据结构,这几个数据结构的定义方法如下:
①基本数据项结构
typedefstruct_TV_ITEM{
UINTmask;
//结构成员有效性屏蔽位
HTREEITEMhItem;
//数据项控制句柄
UINTstate;
//数据项状态
UINTstateMask;
//状态有效性屏蔽位
LPSTRpszText;
//数据项名称字符串
intcchTextMax;
//数据项名称的最大长度
intiImage;
//数据项图标索引号
intiSelectedImage;
//选中数据项图标索引号
intcChildren;
//子项标识
LPARAMlParam;
//程序定义的32位数据
}TV_ITEM,FAR*LPTV_ITEM;
②插入树项结构
typedefstruct_TV_INSERTSTRUCT{
HTREEITEMhParent;
//父项控制句柄
HTREEITEMhInsertAfter;
//插入树项的位置
TV_ITEMitem;
//数据项的结构
}TV_INSERTSTRUCT,FAR*LPTV_INSERTSTRUCT;
其中插入的位置如果是TVI_FIRST或TVI_LAST,则分别插入到树控制的最前面或最后面,如果是TVI_SORT,则插入的树项自动插入到合适的位置。
③树控制通知消息结构
typedefstruct_NM_TREEVIEW{
NMHDRhdr;
//通知消息句柄
UINTaction;
//通知消息标志
TV_ITEMitemOld;
//原来的数据结构
TV_ITEMitemNew;
//新的数据结构
POINTptDrag;
//拖动指针
}NM_TREEVIEW;
④取得或设置数据结构
typedefstruct_TV_DISPINFO{tvdi
//通知消息控制句柄
//数据项结构
}TV_DISPINFO;
⑤指针测试数据结构
typedefstruct_TVHITTESTINFO{tvhtst
POINTpt;
//客户区域屏幕坐标指针
UINTflags;
//存放测试结果的变量
//测试的数据项结构
}TV_HITTESTINFO,FAR*LPTV_HITTESTINFO;
其中flags测试结果可以是如下值:
TVHT_ABOVE在客户区域上面
TVHT_BELOW在客户区域下面
TVHT_NOWHERE在客户区域中并在最后一项下面
TVHT_ONITEM在与树项关联的位图或标签内
TVHT_ONITEMBUTTON在与树项关联的按钮上
TVHT_ONITEMICON在与树项关联的位图上
TVHT_ONITEMINDENT在与树项关联的联线上
TVHT_ONITEMLABEL在与树项关联的标签上
TVHT_ONITEMRIGHT在树项的右侧区域中
TVHT_ONITEMSTATEICON在用户定义的状态图标上
TVHT_TOLEFT在客户区域的左侧
TVHT_TORIGHT在客户区域的右侧
(四)树控制的应用技巧示例
这里仍以基于对话框演示实例来具体介绍树控制及其和图像列表相结构的应用技巧:
通过“FILE->
NEW->
PROJECTS->
MFCAppWizard(EXE)”建立名为VCTREE的工程,在建立过程中选择基于对话框(Dialogbased)的应用;
将对话框中的默认控件删除,并将所有对话框属性中的Language域设置为Chinese(P.R.C.),以使应用程序支持中文;
建立两个图标IDI_PM和IDI_CJ,用来表示图标的选中和非选中状态,对于每个图标都应建立32X32和16X16两种大小,以保证程序的需要;
在对话框窗口中添加树控制对象(TREECONTROL),并设置五个按钮“增加|删除|查看|排序|关闭”,其对应标识分别如下:
控制名称标题名称标识符号
树控制IDC_TREECTRL
按钮增加IDC_ADD
删除IDC_DEL
查看IDC_VIEW
排序IDC_SORT
关闭IDOK
5、选中树控制控件,选择“VIEW->
ClassWizard->
MemoryVariables。
骺刂艻DC_TREECTRL引入成员变量,其变量类型为:
变量名种类变量类型
m_TreeCtrlControlCTreeCtrl
同时利用“MESSAGESMAP”为各命令按钮增加控制功能函数。
6、然后在代码文件VCTREEDlg.CPP中分别加入如下控制代码:
(1)在文件开始处增加图像列表定义
CImageListCil1,Cil2;
//大小图标像列表
(2)在初始化文件开始处增加代码
BOOLCVCTREEDlg:
OnInitDialog()
{CDialog:
OnInitDialog();
......//原来其它代码
//TODO:
Addextrainitializationhere
//此处开始增加代码
CVCTREEApp*pApp=(CVCTREEApp*)AfxGetApp();
//创建图象列表
Cil1.Create(16,16,ILC_COLOR,2,2);
Cil1.Add(pApp->
LoadIcon(IDI_PM));
LoadIcon(IDI_CJ));
m_TreeCtrl.SetImageList(&
Cil1,TVSIL_NORMAL);
//设置图象列表
DWORDdwStyles=GetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE);
//获取树控制原风格
dwStyles|=TVS_EDITLABELS|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT;
SetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE,dwStyles);
//设置风格
char*CJ[4]={"
玉溪卷烟厂"
"
云南卷烟厂"
沈阳卷烟厂"
成都卷烟厂"
};
//根数据名称
char*PM[4][5]={
{"
红梅一"
红梅二"
红梅三"
红梅四"
红梅五"
},//产品数据项
白梅一"
白梅二"
白梅三"
白梅四"
白梅五"
},
绿梅一"
绿梅二"
绿梅三"
绿梅四"
绿梅五"
青梅一"
青梅二"
青梅三"
青梅四"
青梅五"
}};
inti,j;
HTREEITEMhRoot,hCur;
//树控制项目句柄
TV_INSERTSTRUCTTCItem;
//插入数据项数据结构
TCItem.hParent=TVI_ROOT;
//增加根项
TCItem.hInsertAfter=TVI_LAST;
//在最后项之后
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
//设屏蔽
TCItem.item.pszText="
数据选择"
;
TCItem.item.lParam=0;
//序号
TCItem.item.iImage=0;
//正常图标
TCItem.item.iSelectedImage=1;
//选中时图标
hRoot=m_TreeCtrl.InsertItem(&
TCItem);
//返回根项句柄
for(i=0;
i<
4;
i++){//增加各厂家
TCItem.hParent=hRoot;
TCItem.item.pszText=CJ[i];
TCItem.item.lParam=(i+1)*10;
//子项序号
hCur=m_TreeCtrl.InsertItem(&
for(j=0;
j<
5;
j++){//增加各产品
TCItem.hParent=hCur;
TCItem.item.pszText=PM[i][j];
TCItem.item.lParam=(i+1)*10+(j+1);
m_TreeCtrl.InsertItem(&
}
m_TreeCtrl.Expand(hCur,TVE_EXPAND);
//展开树
m_TreeCtrl.Expand(hRoot,TVE_EXPAND);
//展开上一级树
returnTRUE;
//returnTRUEunlessyousetthefocustoacontrol
(3)增加树项功能的实现
在增加树项功能时,除了需要定义和设置插入树项的数据结构之外,还需要注意的是新增树项的名称初始时均为“新增数据”,增加后允许用户给数据项设置自定义名称。
在编程时应特别注意m_TreeCtrl.EditLabel(hInsert);
后面不能跟任何其它程序命令,否则这条编辑指令无效。
voidCVCTREEDlg:
OnAdd()
{//增加子项功能函数
HTREEITEMhSel=m_TreeCtrl.GetSelectedItem();
//取得选择项句柄
if(hSel==NULL)return;
//无任何选项则返回
staticintnAddNo=100;
//编号大于100为新增数据
//定义插入项数据结构
TCItem.hParent=hSel;
//设置父项句柄
//在最后增加
新增数据"
TCItem.item.lParam=nAddNo++;
//索引号增加
HTREEITEMhInsert=m_TreeCtrl.InsertItem(&
//增加
m_TreeCtrl.Expand(hSel,TVE_EXPAND);
m_TreeCtrl.EditLabel(hInsert);
//修改增加的数据
(4)删除树项功能的实现
在实现删除功能时,应对存在子项的树项进行提示,以警告用户是否连同其子项一起删除。
OnDel()
{//删除子项功能函数
//取得选项句柄;
if(m_TreeCtrl.ItemHasChildren(hSel))//判断是否有子项
if(MessageBox("
厂家下存在品名,一同删除?
"
警告"
MB_YESNO)==IDNO)return;
m_TreeCtrl.DeleteItem(hSel);
(5)排序功能的实现
排序功能是对所选中的树项的所有子项按字符中顺序进行排序,如果想要按照其它规则进行排序,应利用SortChildrenItemBC()函数进行自行开发排序程序,这个自行开发的函数与列表控制中实现的函数基本相同,可兴趣的读可以试验。
OnSort()
{//排序子项功能函数
m_TreeCtrl.SortChildren(hSel);
(6)查看功能的实现
查看功能用来查看选中树项的有关信息,函数中中显示了树项的文本名称和标识号,可以将这两个信息作为查找关键字,来查看其它更详细的信息。
OnView()
{//查看选中项功能函数
CStringcText=m_TreeCtrl.GetItemText(hSel);
//取得数据项名
LONGIDs=m_TreeCtrl.GetItemData(hSel);
//取得数据项序号
chartemp[100];
wsprintf(temp,"
厂家:
%s编号:
%05d"
cText,IDs);
MessageBox(temp,"
选择信息"
);
(7)修改功能的实现
如果不进行其它处理,当修改树项的文本名称后,就会发现其未被修改,这是因为程序中没有对修改结果进行保存处理,这就要利用TV_DISPINFO结构和SetItemText函数对TVN_ENDLABELEDIT进行处理,这样就可以正确地实现修改功能。
OnEndlabeleditTree(NMHDR*pNMHDR,LRESULT*pResult)
{TV_DISPINFO*pTVDispInfo=(TV_DISPINFO*)pNMHDR;
Addyourcontrolnotificationhandlercodehere
if(pTVDispInfo->
item.pszText==0)return;
//用户取消修改操作
m_TreeCtrl.SetItemText(pTVDispInfo->
item.hItem,
pTVDispInfo->
item.pszText);
//设置新数据
*pResult=0;
7、树视的演练技巧
树视的应用技巧在使用树视时,其方法与树控制基本相同,只不过树视是在窗口中来实现的而树控制是在对话框中实现,树视的各种功能是通过菜单来实现的而树控制是通过按钮等方式来实现的,树控制需要在对话框中创建树控制控件而树视直接占据整个窗口,在设计过程中只要将按钮和树控制设计过程变为菜单设计,并注意在功能函数是在类向导中是通过菜单命令来操作,同时在每个功能函数前面增加取得列表视引用的命令(CTreeCtrl&
TreeCtrl=GetTreeCtrl()),而其余数据结构和代码均不需要修改,实现起来比较容易。