数据库构建TreeTree如下:
 设备一览表   
   |   
   |--01.00.00.00
   |         |
   |         |
   |         | --01.01.00.00
   |         |        |
   |         |        |--01.01.00.00
   |         |              | 
   |         |              |--01.01.01.00
   |         |                      |
   |         |                      |--01.01.01.01
   |         |
   |         |--01.02.00.00
   |    
   |
   |--02.00.00.00
 数据库是这样的 (这几个我只是举的几个例子,不局限于这几个,实际应用中有很多个IDChild )
 ID    IDChild          IDParent
 0     01.00.00.00       NULL 
 1     01.01.00.00       01.00.00.00 
 2     01.01.01.00       01.01.00.00     
 3     01.01.01.01       01.01.01.00  
 4     01.02.00.00       01.00.00.00     
 5     02.00.00.00       NULL
                         void CDlgTree::InitTreeCtrl(void)  //我要用数据库构建Tree 《----这个函数就是
{
    m_imgState.Create(IDB_BITMAP_STATE,13,1,RGB(255,255,255));
    m_treeSet.SetImageList(&m_imgState,TVSIL_STATE);//设置选中和未选中时显示状态
    HTREEITEM parentItem=m_treeSet.InsertItem("设备一览表)",0,1); HRESULT hr;
    _RecordsetPtr pRentRecordset;
    hr=pRentRecordset.CreateInstance(_uuidof(Recordset));
    if(FAILED(hr))
    {
   AfxMessageBox("createinstance of Recordset failed! ");
   return;
    }
        CString strSql;
        _variant_t varChild,varParent;
CString strValue1,strValue2;
int curItem;
        strSql="SELECT * FROM TreeData";
try
{
hr=pRentRecordset->Open(_variant_t(strSql),m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
if(SUCCEEDED(hr))
{
   pRentRecordset->MoveFirst();
                   while(!pRentRecordset->adoEOF)
   {             
                           varChild=pRentRecordset->GetCollect((long)1); //IDChild
   varParent=pRentRecordset->GetCollect((long)2);// IDParent
     if(varChild.vt!=VT_NULL)
     {   
                                //怎么操作数据?????           
     }
                   pRentRecordset->MoveNext();
   }
}
}
catch(_com_error *e)
{ }
}
    数据库都连接成功,关键就是不知道怎么操作得到的数据来构建Tree.希望好人能帮我把代码补充完整,谢谢````

解决方案 »

  1.   

    程序已经弄出来了,但总是调试出错  
           我把程序列出来大家帮我看哈问题在那里void CDlgTree::InitTreeCtrl(void)
    {
        m_imgState.Create(IDB_BITMAP_STATE,13,1,RGB(255,255,255));
        m_treeSet.SetImageList(&m_imgState,TVSIL_STATE);//设置选中和未选中时显示状态
        HTREEITEM parentItem=m_treeSet.InsertItem("设备一览表)",0,1);
    HRESULT hr;
        _RecordsetPtr pRentRecordset;
        hr=pRentRecordset.CreateInstance(_uuidof(Recordset));
        if(FAILED(hr))
        {
       AfxMessageBox("createinstance of Recordset failed! ");
       return;
        }
        CString strSql;
        _variant_t varChild,varParent;
    CString strValue1,strValue2;
    int curItem;
        strSql="SELECT * FROM TreeData WHERE IDParent is NULL";
    try
    {
    hr=pRentRecordset->Open(_variant_t(strSql),m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
    if(SUCCEEDED(hr))
    {
       pRentRecordset->MoveFirst();
               while(!pRentRecordset->adoEOF)
       {             
                   varChild=pRentRecordset->GetCollect((long)1);
       varParent=pRentRecordset->GetCollect((long)2);
       if(varChild.vt!=VT_NULL)
        {   
                        AddItem(varChild,parentItem);         
        }  
       pRentRecordset->MoveNext();
       }
    }
    }
    catch(_com_error *e)
    {
    AfxMessageBox(e->ErrorMessage());
    return;
    }
    pRentRecordset->Close();
        pRentRecordset=NULL;
    }
    void CDlgTree::AddItem(_variant_t varChild,HTREEITEM parentItem)
    {
       HRESULT hr;
       CString strSql,strChild;
       _RecordsetPtr pRentRecordset;
       hr=pRentRecordset.CreateInstance(_uuidof(Recordset));
       if(FAILED(hr))
       {
       AfxMessageBox("createinstance of Recordset failed! ");
       return;
       }
       HTREEITEM NewItem,Item;
       NewItem =m_treeSet.InsertItem((LPCTSTR)(_bstr_t)varChild,parentItem,TVI_SORT);  
         
       strChild=varChild;
       strSql = "SELECT * FROM TreeData WHERE IDParent=" + strChild;
       try
       {
         //这一句内存总出错
         hr=pRentRecordset->Open(_variant_t(strSql),m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
         if(SUCCEEDED(hr))
     {
        pRentRecordset->MoveFirst();
            while(!pRentRecordset->adoEOF)

               varChild=pRentRecordset->GetCollect((long)1);
               Item =m_treeSet.InsertItem((LPCTSTR)(_bstr_t)varChild,NewItem,TVI_SORT);
               pRentRecordset->MoveNext();
        }
       
           AddItem(varChild,Item);
     }
       }
       catch(_com_error *e)
    {
    AfxMessageBox(e->ErrorMessage());
    return;
    }
    pRentRecordset->Close();
        pRentRecordset=NULL;}
       
      

  2.   

    数据库构建Tree Tree如下: 
    设备一览表  
      ¦  
      ¦--01.00.00.00 
      ¦        ¦ 
      ¦        ¦ 
      ¦        ¦ --01.01.00.00 
      ¦        ¦        ¦ 
      ¦        ¦        ¦--01.01.00.00 
      ¦        ¦              ¦ 
      ¦        ¦              ¦--01.01.01.00 
      ¦        ¦                      ¦ 
      ¦        ¦                      ¦--01.01.01.01 
      ¦        ¦ 
      ¦        ¦--01.02.00.00 
      ¦    
      ¦ 
      ¦--02.00.00.00 
    数据库是这样的 (这几个我只是举的几个例子,不局限于这几个,实际应用中有很多个IDChild ) 
    ID    IDChild          IDParent 
    0    01.00.00.00      NULL 
    1    01.01.00.00      01.00.00.00 
    2    01.01.01.00      01.01.00.00    
    3    01.01.01.01      01.01.01.00  
    4    01.02.00.00      01.00.00.00    
    5    02.00.00.00      NULL 
                            
    void CDlgTree::InitTreeCtrl(void)   //我要用数据库构建Tree 《----这个函数就是 {
        m_imgState.Create(IDB_BITMAP_STATE,13,1,RGB(255,255,255));
        m_treeSet.SetImageList(&m_imgState,TVSIL_STATE);//设置选中和未选中时显示状态
        HTREEITEM parentItem=m_treeSet.InsertItem("设备一览表)",0,1);
    HRESULT hr;
        _RecordsetPtr pRentRecordset;
        hr=pRentRecordset.CreateInstance(_uuidof(Recordset));
        if(FAILED(hr))
        {
       AfxMessageBox("createinstance of Recordset failed! ");
       return;
        }
         CString strSql;
         _variant_t varChild,varParent;
         CString strValue1,strValue2;
         int curItem;
         strSql="SELECT * FROM TreeData WHERE IDParent is NULL";
    try
    {
    hr=pRentRecordset->Open(_variant_t(strSql),m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
    if(SUCCEEDED(hr))
    {
      pRentRecordset->MoveFirst();
              while(!pRentRecordset->adoEOF)
      {             
                  varChild=pRentRecordset->GetCollect((long)1);
                  varParent=pRentRecordset->GetCollect((long)2);
           if(varChild.vt!=VT_NULL)
           {   
                     AddItem(varChild,parentItem);         
           }  
             pRentRecordset->MoveNext();
      }
    }
    }
    catch(_com_error *e)
    {
        AfxMessageBox(e->ErrorMessage());
        return;
    }
    pRentRecordset->Close();
            pRentRecordset=NULL;
    }
    void CDlgTree::AddItem(_variant_t varChild,HTREEITEM parentItem)//使用到了递归
    {
       HRESULT hr;
       CString strSql,strChild;
       _RecordsetPtr pRentRecordset;
       hr=pRentRecordset.CreateInstance(_uuidof(Recordset));
       if(FAILED(hr))
       {
            AfxMessageBox("createinstance of Recordset failed! ");
    return;
       }
       HTREEITEM NewItem,Item;
       NewItem =m_treeSet.InsertItem((LPCTSTR)(_bstr_t)varChild,parentItem,TVI_SORT);      
       strChild=varChild;
       strSql = "SELECT * FROM TreeData WHERE IDParent=" + strChild;
       try
       {
         //问题在这
         hr=pRentRecordset->Open(_variant_t(strSql),m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
         if(SUCCEEDED(hr))
     {
        pRentRecordset->MoveFirst();
                while(!pRentRecordset->adoEOF)
       { 
                  varChild=pRentRecordset->GetCollect((long)1);
                  Item =m_treeSet.InsertItem((LPCTSTR)(_bstr_t)varChild,NewItem,TVI_SORT);
                  pRentRecordset->MoveNext();
       }
       
                 AddItem(varChild,Item);
     }
       }
       catch(_com_error *e)
    {
       AfxMessageBox(e->ErrorMessage());
               return;
    }
    pRentRecordset->Close();
            pRentRecordset=NULL;}
       
      

  3.   

    我试了你的代码,异常的问题在于你的SQL语句有问题。
    我使用的SQL server来测试的。
    IDParent的类型是nvarchar,
    而异常时,open执行的SQL语句是SELECT * FROM TreeData WHERE IDParent=01.00.00.00
    WHERE后面的条件,类型不匹配。
    楼主应该这样:
    SELECT * FROM TreeData WHERE IDParent='01.00.00.00'
    (字符串要加单引号)
    而且我继续执行时发现:
    pRentRecordset->MoveFirst(); 
    这条语句也会异常,这里不用MoveFirst
    直接这样就可以:
    while(!pRentRecordset->adoEOF) 
      

  4.   

    另外,楼主的AddItem函数中使用了递归,但是有问题,在调试一下吧。
      

  5.   


    这个问题已经解决了  谢谢大家的热心 特别谢谢primer_programer       我在这里另外加一个问题(不好意思)呵呵
       我是个分割窗口我的左边是上面的Tree右边是FormView  我想在FormView上放一个CTabCtrl,这个CTabCtrl和FormView同大同小,但是我改变这个FormView的大小的时候CTabCtrl下面就没有了比如下面有控件改小以后FormView旁边出现滚动条下面的控件就消失了,他只显示一定的大小,没有按比例改变大小和位置  大侠们帮忙看哈  这个搞完马上给分
     谢谢
      

  6.   

    代码是这样的    我在线等答案
     
       IMPLEMENT_DYNCREATE(CMonitorView, CFormView)BEGIN_MESSAGE_MAP(CMonitorView, CFormView)
    ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTab1)
    ON_WM_SIZE()
    END_MESSAGE_MAP()// CMonitorView 构造/析构CMonitorView::CMonitorView()
    : CFormView(CMonitorView::IDD)
    {
    // TODO: 在此处添加构造代码}CMonitorView::~CMonitorView()
    {
    }void CMonitorView::DoDataExchange(CDataExchange* pDX)
    {
    CFormView::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_TAB1, m_tabCtrl);
    }BOOL CMonitorView::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
    // 样式 return CFormView::PreCreateWindow(cs);
    }void CMonitorView::OnInitialUpdate()
    {
    CFormView::OnInitialUpdate();
    GetParentFrame()->RecalcLayout();
    ResizeParentToFit();
    DWORD dwStyle = m_tabCtrl.GetExStyle();
        m_tabCtrl.SetExtendedStyle(dwStyle|WS_CHILD);
        TCITEM tcItem1;
        tcItem1.mask = TCIF_TEXT;
        tcItem1.pszText = _T("Tab 1");
        m_tabCtrl.InsertItem(0, &tcItem1); 
        TCITEM tcItem2;
        tcItem2.mask = TCIF_TEXT;
        tcItem2.pszText = _T("Tab 2");
        m_tabCtrl.InsertItem(1, &tcItem2);  
        TCITEM tcItem3;
        tcItem3.mask = TCIF_TEXT;
        tcItem3.pszText = _T("Tab 3");
        m_tabCtrl.InsertItem(2, &tcItem3); 
    m_tab1.Create(IDD_DLG_TAB1,this);
    m_tab2.Create(IDD_DLG_TAB2,this);
    m_tab3.Create(IDD_DLG_TAB3,this);}// CMonitorView 诊断#ifdef _DEBUG
    void CMonitorView::AssertValid() const
    {
    CFormView::AssertValid();
    }void CMonitorView::Dump(CDumpContext& dc) const
    {
    CFormView::Dump(dc);
    }CMonitorDoc* CMonitorView::GetDocument() const // 非调试版本是内联的
    {
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMonitorDoc)));
    return (CMonitorDoc*)m_pDocument;
    }
    #endif //_DEBUG
    // CMonitorView 消息处理程序void CMonitorView::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
    {
       int ID = m_tabCtrl.GetCurSel();       
       ShowChild(ID);  
       *pResult = 0;
    }void  CMonitorView::ShowChild(int ID)   
    {   
       m_tab1.ShowWindow((ID  ==  0)? SW_SHOW : SW_HIDE);   
       m_tab2.ShowWindow((ID  ==  1)? SW_SHOW : SW_HIDE);  
       m_tab3.ShowWindow((ID  ==  2)? SW_SHOW : SW_HIDE); 
    } void CMonitorView::OnSize(UINT nType, int cx, int cy)
    {
    CFormView::OnSize(nType, cx, cy);
        
        RECT rect,tabRect; 
        GetClientRect(&rect);   
        tabRect.top    = rect.top;   
        tabRect.left   = rect.left;   
        tabRect.bottom = rect.bottom ;   
        tabRect.right  = rect.right ;      if(m_tabCtrl.GetSafeHwnd()!=NULL)
    {
    m_tabCtrl.MoveWindow(&tabRect); CRect itemRect;
    m_tabCtrl.GetItemRect(0,&itemRect); tabRect.top = itemRect.bottom+15; if(::IsWindow(m_tab1.m_hWnd))
    {
      m_tab1.SetWindowPos(&wndTop,tabRect.left,tabRect.top,tabRect.right-10,tabRect.bottom-50,SWP_SHOWWINDOW);
      m_tab2.SetWindowPos(&wndTop,tabRect.left,tabRect.top,tabRect.right-10,tabRect.bottom-50,SWP_HIDEWINDOW);
      m_tab3.SetWindowPos(&wndTop,tabRect.left,tabRect.top,tabRect.right-10,tabRect.bottom-50,SWP_HIDEWINDOW);
    }
    }
    }
      
      

  7.   

    我把问题在说清楚一点  怕各位仁兄看不懂
      
      我是个分割窗口我的左边是上面的Tree右边是FormView  我想在FormView上放一个CTabCtrl,这个CTabCtrl和FormView同大同小,但是我改变这个FormView的大小的时候CTabCtrl的Page页上底部的控件就被盖住消失了(也就是说改变FormView的大小Page页上的控件位置没有按比例发生相应变化,还是在原地方,导致FormView变小的时候,下面的控件就消失) 
       我改了点别的小问题,代码贴出,希望大家帮忙
       
                IMPLEMENT_DYNCREATE(CMonitorView, CFormView)BEGIN_MESSAGE_MAP(CMonitorView, CFormView)
    ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTab1)
    ON_WM_SIZE()
    END_MESSAGE_MAP()// CMonitorView 构造/析构CMonitorView::CMonitorView()
    : CFormView(CMonitorView::IDD)
    {
    // TODO: 在此处添加构造代码}CMonitorView::~CMonitorView()
    {
    }void CMonitorView::DoDataExchange(CDataExchange* pDX)
    {
    CFormView::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_TAB1, m_tabCtrl);
    }BOOL CMonitorView::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
    // 样式 return CFormView::PreCreateWindow(cs);
    }void CMonitorView::OnInitialUpdate()
    {
    CFormView::OnInitialUpdate();
    GetParentFrame()->RecalcLayout();
    ResizeParentToFit();
    DWORD dwStyle = m_tabCtrl.GetExStyle();
        m_tabCtrl.SetExtendedStyle(dwStyle|WS_CHILD);
        TCITEM tcItem1;
        tcItem1.mask = TCIF_TEXT;
        tcItem1.pszText = _T("Tab 1");
        m_tabCtrl.InsertItem(0, &tcItem1); 
        TCITEM tcItem2;
        tcItem2.mask = TCIF_TEXT;
        tcItem2.pszText = _T("Tab 2");
        m_tabCtrl.InsertItem(1, &tcItem2);  
        TCITEM tcItem3;
        tcItem3.mask = TCIF_TEXT;
        tcItem3.pszText = _T("Tab 3");
        m_tabCtrl.InsertItem(2, &tcItem3); 
    m_tab1.Create(IDD_DLG_TAB1,this);
    m_tab2.Create(IDD_DLG_TAB2,this);
    m_tab3.Create(IDD_DLG_TAB3,this);}// CMonitorView 诊断#ifdef _DEBUG
    void CMonitorView::AssertValid() const
    {
    CFormView::AssertValid();
    }void CMonitorView::Dump(CDumpContext& dc) const
    {
    CFormView::Dump(dc);
    }CMonitorDoc* CMonitorView::GetDocument() const // 非调试版本是内联的
    {
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMonitorDoc)));
    return (CMonitorDoc*)m_pDocument;
    }
    #endif //_DEBUG
    // CMonitorView 消息处理程序void CMonitorView::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
    {
       int ID = m_tabCtrl.GetCurSel();       
       ShowChild(ID);  
       *pResult = 0;
    }void  CMonitorView::ShowChild(int ID)   
    {   
       m_tab1.ShowWindow((ID  ==  0)? SW_SHOW : SW_HIDE);   
       m_tab2.ShowWindow((ID  ==  1)? SW_SHOW : SW_HIDE);  
       m_tab3.ShowWindow((ID  ==  2)? SW_SHOW : SW_HIDE); 
    } void CMonitorView::OnSize(UINT nType, int cx, int cy)
    {
    CFormView::OnSize(nType, cx, cy);
        
        RECT rect,tabRect; 
        GetClientRect(&rect);   
        tabRect.top    = rect.top;   
        tabRect.left   = rect.left;   
        tabRect.bottom = rect.bottom ;   
        tabRect.right  = rect.right ;      if(m_tabCtrl.GetSafeHwnd()!=NULL)
    {
    m_tabCtrl.MoveWindow(&tabRect); CRect itemRect;
    m_tabCtrl.GetItemRect(0,&itemRect);
    tabRect.top = itemRect.bottom+15; if(::IsWindow(m_tab1.m_hWnd))
    {
      m_tab1.SetWindowPos(&wndTop,tabRect.left,tabRect.top,tabRect.right-10,tabRect.bottom-50,SWP_SHOWWINDOW);
      int ID = m_tabCtrl.GetCurSel();
      m_tab1.ShowWindow((ID  ==  0)? SW_SHOW : SW_HIDE);   
              m_tab2.ShowWindow((ID  ==  1)? SW_SHOW : SW_HIDE);  
              m_tab3.ShowWindow((ID  ==  2)? SW_SHOW : SW_HIDE); 
    }
    if(::IsWindow(m_tab2.m_hWnd))
    {
      m_tab2.SetWindowPos(&wndTop,tabRect.left,tabRect.top,tabRect.right-10,tabRect.bottom-50,SWP_HIDEWINDOW );
      int ID = m_tabCtrl.GetCurSel();
      m_tab1.ShowWindow((ID  ==  0)? SW_SHOW : SW_HIDE);   
              m_tab2.ShowWindow((ID  ==  1)? SW_SHOW : SW_HIDE);  
              m_tab3.ShowWindow((ID  ==  2)? SW_SHOW : SW_HIDE); 
    }
    if(::IsWindow(m_tab3.m_hWnd))
    {
      m_tab3.SetWindowPos(&wndTop,tabRect.left,tabRect.top,tabRect.right-10,tabRect.bottom-50,SWP_HIDEWINDOW);
      int ID = m_tabCtrl.GetCurSel();
      m_tab1.ShowWindow((ID  ==  0)? SW_SHOW : SW_HIDE);   
              m_tab2.ShowWindow((ID  ==  1)? SW_SHOW : SW_HIDE);  
              m_tab3.ShowWindow((ID  ==  2)? SW_SHOW : SW_HIDE); 
    }
    }
    }
      
       
              
         
       
      

  8.   


    一个小问题 VC 2003为什么不能传BitMap上去呀,,不知道大家遇到了吗``