分享
 
 
 

按数据库记录构建树控件

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

按数据库记录构建树控件

作者:XuFeng Yuan

下载本文示例代码

代码运行效果图如下:

简介:

将树中的每一个项目作为数据库中的一条记录(ACCESS2000),将程序启动时,对数据库进行读操作;创建树的各个项目时,是对数据库进行读操作,每次的读取,都是在可是查寻符合条件的记录,并将其一一添加到树中!

实现方法:

准备:

使用ACCESS2000,创建一个数据库,名字为City.mdb(我们将制作一个关于省与市的树,特别适合通讯录);

在数据库中创建一表,表名为TreeItem,字段内容与类型如下图:

ID: 索引号码(可有,可无)

Name: 项目名称(必须)

ParentItem: 父项名称(必须)

SecNum: 电话区号(可有,可无)

输入一些原始数据.数据库已经准备好,那我们就进行实地的编程阶段.

程序实现:

创建一个基于对话框的工程---TreeData

一.ADO的引入和初始化

由于在程序中,我使用了ADO来连接和操作数据库,所以要进行以下操作:

1.在Stdafx.h中添加引作ADO的代码:

//--------------------------------------------

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")

//--------------------------------------------

2.在TreeData.h中声明两个私有变量:

public:

_ConnectionPtr m_pTreeConn;//连接创建

private:

CString TreeConnString;//连接字符串

3.在CTreeDataApp的构造函数CTreeDataApp中添加如下代码:

//-------------------------------------------

m_TreeConnString=_T("Provider=Microsoft.Jet.OLEDB.4.0;")

_T("Data Source=DataBase\\City.mdb;");

//-------------------------------------------

4.在CTreeDataApp的初始化函数中添加如下代码:

//-------COM初始化--------------------------------

AfxOleInit();

/******************连接通讯录数据库********************/

HRESULT hRes;

try

{

hRes=m_pTreeConn.CreateInstance(_T("ADODB.Connection"));

m_pTreeConn-ConnectionTimeout = 8;

//连接ACCESS2000

hRes=m_pTreeConn-Open(_bstr_t((LPCTSTR) m_strTelDataSource),

_T(""),_T(""),adModeUnknown);

}

catch(_com_error e)///捕捉异常

{

CString errormessage;

errormessage.Format(_T("连接TelBook.mdb数据库失败!\r\n错误信息:%s"),e.ErrorMessage());

AfxMessageBox(errormessage);///显示错误信息

return FALSE;

}

二.Recordset的创建:

1.在CTreeDataDlg.h中声明变量:

//------------------------------------------

private:

HRESULT hRes;

_RecordsetPtr m_TreeRecordset; //用于创建一个查询记录集

//------------------------------------------

public:

CImageList m_TreeBootImage; //Tree的图标

2. (1).在对话框窗口中添加一个TreeCtrl控件,一个ComboExe控件; TreeCtrl的风格设置如下图;

(2).导入一个BMP文件,做为Tree的项目图标(TreeBoot.bmp),将其ID设置为IDB_TreeBootImage;

(3).在向导中,为三个控件添加连接对象.

3.在CTreeDataDlg中右击,选择添加一个成员函数TreeAddTree(bool Ta):

void CBusinessView::TreeAddTree(bool Ta)

{

//--------------Tree控件操作变量------------------------

TVINSERTSTRUCT tvInsert;

HTREEITEM hParent;

//------------------------------------------------

tvInsert.hParent = NULL;

tvInsert.hInsertAfter = NULL;

tvInsert.item.mask = TVIF_TEXT;

//-----------------创建图象标签----------------------------

m_TreeBootImage.Create ( IDB_TreeBootImage,20,1,ILC_COLOR8);

m_ctrlTree.SetImageList ( &m_TreeBootImage,TVSIL_NORMAL );

m_ctrlTree.SetTextColor (RGB(7,145,13));

//--------添加根目录----------------------------------------

tvInsert.item.pszText = _T("中国");

hParent = m_ctrlTree.InsertItem(&tvInsert);

//---------------添加子目录-------------------------------

TreeAddSubTree("中国","1",hParent);

//---------------------展开Tree目录------------------

m_ctrlTree.Expand(hParent,TVE_EXPAND);

}

4.添加一个COM变量到CString变量的转换函数:

//-----------------实现了VARIANT类型的值转换成CString类型--------------

CString CBusinessView::VariantToCString(VARIANT var)

{

CString strValue;

_variant_t var_t;

_bstr_t bst_t;

time_t cur_time;

CTime time_value;

COleCurrency var_currency;

switch(var.vt)

{

case VT_EMPTY:strValue=_T("");break;

case VT_UI1:strValue.Format ("%d",var.bVal);break;

case VT_I2:strValue.Format ("%d",var.iVal );break;

case VT_I4:strValue.Format ("%d",var.lVal);break;

case VT_R4:strValue.Format ("%f",var.fltVal);break;

case VT_R8:strValue.Format ("%f",var.dblVal);break;

case VT_CY:

var_currency=var;

strValue=var_currency.Format(0);

break;

case VT_BSTR:

var_t=var;

bst_t=var_t;

strValue.Format ("%s",(const char*)bst_t);

break;

case VT_NULL: strValue=_T(""); break;

case VT_DATE:

cur_time=var.date;

time_value=cur_time;

strValue=time_value.Format("%A,%B%d,%Y");

break;

case VT_BOOL: strValue.Format ("%d",var.boolVal ); break;

default: strValue=_T(""); break;

}

return strValue;

}

5.同样的方法添加另外一个成员函数TreeAddSubTree(CString

ParTree,CString strChildTree,HTREEITEM hPartItem):

此成员函数是一个递归函数.

if (strChildTree!="0")

{

//----------------使用到的变量进行定义----------

_RecordsetPtr m_pTreeRecordset; //用于创建一个查询记录集

_variant_t vChild;

//--------------Tree控件操作变量------------------------

HTREEITEM hCurrent;

//----------------------------------------------

CString strSQL,strCurItem;

//-----------------------------------------------

strSQL="SELECT * FROM TreeItem where ParentItem like ''%" ;

strSQL=strSQL+ParTree+"%''";

try

{

HRESULT hTRes;

hTRes = m_pTreeRecordset.CreateInstance(_T("ADODB.Recordset"));

if (SUCCEEDED(hTRes))

{

//----------------------------------------------------

hTRes = m_pTreeRecordset-Open((LPTSTR)strSQL.GetBuffer(130),

_variant_t((IDispatch *)(((CBusinessApp*)AfxGetApp())-m_pTreeConnection),true),

adOpenDynamic,adLockPessimistic,adCmdText);

if(SUCCEEDED(hTRes))

{

TRACE(_T("连接成功!\n"));

//------------------------------------------

m_pTreeRecordset-MoveFirst();

if (!(m_pTreeRecordset-adoEOF))

{

while(!m_pTreeRecordset-adoEOF)

{

hCurrent = m_ctrlTree.InsertItem((LPCTSTR)(_bstr_t)(m_pTreeRecordset-GetCollect("Name")), hPartItem, NULL);

//---------------将内容添加到City的Combo控件中------------------

m_ctrlComboCity.AddString(VariantToCString(m_pTreeRecordset-GetCollect("Name")));

if (TreeSumRecordCount(VariantToCString(m_pTreeRecordset-GetCollect("Name")))0)

{

TreeAddSubTree(VariantToCString(m_pTreeRecordset-GetCollect("Name")),

(VariantToCString(m_pTreeRecordset-GetCollect("Name"))),

hCurrent);

}

if (!(m_pTreeRecordset-adoEOF))

{

m_pTreeRecordset-MoveNext();

}

}

}

//---------------------------------------

}

}

}

catch(_com_error e)///捕捉异常

{

CString errormessage;

MessageBox("创建City记录集失败!",ParTree+strChildTree);

}

}

6.添加一个求当前项子项串的成员函数ReturnTreeChilds(CString

strCurItem):

此成员函数也是递归函数.

//----------------提取当前所选择项的子项文本所组成的字符串------------------------

CString CTreeDataDlg::ReturnTreeChilds(CString strCurItem)

{

CString strTreeChildren;//记录子项文本所组成的字符串

if (TreeSumRecordCount(strCurItem) 0)

{

//--------------------进入递归运算---------------------

_RecordsetPtr m_pTreeRecordset; //用于创建一个查询记录集

_variant_t vCur;

CString strSQL;

//-----------------------------------------------

strSQL="SELECT * FROM TreeItem where ParentItem like ''%" ;

strSQL=strSQL+strCurItem+"%''";

try

{

HRESULT hTRes;

hTRes = m_pTreeRecordset.CreateInstance(_T("ADODB.Recordset"));

if (SUCCEEDED(hTRes))

{

//----------------------------------------------------

hTRes = m_pTreeRecordset-Open((LPTSTR)strSQL.GetBuffer(130),

_variant_t((IDispatch *)(((CTreeDataApp*)AfxGetApp())-m_pTreeConn),true),

adOpenDynamic,adLockPessimistic,adCmdText);

if(SUCCEEDED(hTRes))

{

TRACE(_T("连接成功!\n"));

//------------------------------------------

m_pTreeRecordset-MoveFirst();

vCur=(m_pTreeRecordset-GetCollect("Name"));

if (TreeSumRecordCount(VariantToCString(vCur))=0)

{

while(!m_pTreeRecordset-adoEOF)

{

vCur=(m_pTreeRecordset-GetCollect("Name"));

strTreeChildren+=(",''"+VariantToCString(vCur)+"''");

if (TreeSumRecordCount(VariantToCString(vCur))!=0)

{

strTreeChildren+=ReturnTreeChilds(VariantToCString(vCur));

}

if (!(m_pTreeRecordset-adoEOF))

{

m_pTreeRecordset-MoveNext();

}

}

}

//---------------------------------------

}

}

}

catch(_com_error e)///捕捉异常

{

CString errormessage;

AfxMessageBox("创建ChildTree记录集失败!"+strCurItem);

}

}

return strTreeChildren;

}

7.处理TreeCtrl控件的点击(OnClick)和改变选择项(SelchangedTree)事件:

void CTreeDataDlg::OnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult)

{

NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

//--------------------------------------------------------

hTreeCurrent=m_ctrlTree.GetSelectedItem ();

hTreeParent=m_ctrlTree.GetParentItem(m_ctrlTree.GetSelectedItem ());

//-------------------树型控件的图标更改---------

m_ctrlTree.SetItemImage(hTreeCurrent,1,true );

//----------------------------------------------

TreeCurrent="''"+m_ctrlTree.GetItemText(hTreeCurrent)+"''";

TreeParent=m_ctrlTree.GetItemText (hTreeParent);

//---------------------处理ListTree中的相应显示内容--------------

//-------------提取树中当前项及其子项的内容------

hTreeCurrent=m_ctrlTree.GetSelectedItem ();

m_strEdit=TreeCurrent+ReturnTreeChilds(m_ctrlTree.GetItemText(hTreeCurrent));

UpdateData(false);//子项内容显示到Edit控件中

//---------------------------------------------------

*pResult = 0;

}

void CTreeDataDlg::OnClickTree1(NMHDR* pNMHDR, LRESULT* pResult)

{

//-------------------树型控件的图标还原---------

m_ctrlTree.SetItemImage(hTreeCurrent,0,true );

//----------------------------------------------

*pResult = 0;

}

三.在BOOL

CTreeDataDlg::OnInitDialog()中添加以下代码:

TreeAddTree();

总结:

这个程序主要是在数据库中进行操作,主干是两个递归成员函数;对于递归,让你自己来理解吧!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有