收藏本站 
广告服务 
网站地图 
>> 我们从网络和杂志上收集了近100000余篇各类电脑技术、网络技术、软件技术等方面的文章教程,我们的收录原则:不是精华拒不收录!
先飞电脑技术网技术文章
用VC实现按数据库记录构建树控件
[ 作者:佚名    转贴自:网络转载    阅读次数:50    更新时间:2007-3-21 13:38:00   录入:刘光勇 ]         
    

 简介:

  将树中的每一个项目作为数据库中的一条记录(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();

  本文效果图:


  总结:

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

上一篇:VC实现在状态栏中加入进度指示器  下一篇: VC++中轻松实现滑动(Slider)控件  

网站主页 | 收藏本页 | 联系我们 | 广告服务 | 站点地图 | 会员注册 | 招聘信息 | 内容指正

联系QQ:先飞电脑技术网站事务联系QQ,点击可以直接留言. 32933427 电话:13710542091 [世界排名] 鄂ICP备05005890号