百度空间 | 百度首页 
 
查看文章
 
按数据库记录构建树(CTreeCtrl)控件
2009年06月26日 星期五 08:13

代码运行效果图如下:


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

总结:

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

【转载自http://www.vckbase.com/document/viewdoc/?id=466


类别:visual c++ | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu