我想实现一个像QQ列表一样的树形结构列表,里边节点总共有4种图标,如图:
我先实现将文件夹排在最前面,接着是彩色图标,最后才是灰色图标,求大牛们指点,给分保证跟上

解决方案 »

  1.   

    图片挂了。。先上传到CSDN相册,然后在插入图片的地址就能显示了 !!
      

  2.   

    shen_wei:
    怎么上传啊?没弄过这
      

  3.   

    自己先给数据排序,CTreeCtrl::InsertItem()时hInsertAfter参数用TVI_LAST,一个一个加进去不就行了。
      

  4.   

    进入你的CSDN博客,里面有相册
      

  5.   

    如果是动态的,简单点可以调CTreeCtrl的SortChildrenCB,通过一个回调函数定义排序规则:
    int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
       //把该函数换成自己的规则
       CTreeCtrl* pmyTreeCtrl = (CTreeCtrl*)lParamSort;
       CString strItem1 = pmyTreeCtrl->GetItemText((HTREEITEM)lParam1);
       CString strItem2 = pmyTreeCtrl->GetItemText((HTREEITEM)lParam2);   return strItem2.Compare(strItem1);
    }TVSORTCB tvs;
    tvs.hParent = TVI_ROOT;
    tvs.lpfnCompare = MyCompareProc;
    tvs.lParam = (LPARAM)&m_TreeCtrl;m_TreeCtrl.SortChildrenCB(&tvs);
      

  6.   


    这个我也试过,tree item data值我已经使用了,但是lParam1和lParam2是连个节点的data值,怎么才能取到与它们对应的节点呢?
      

  7.   

    定义一个链表结构 把所有的节点的句柄全部存储到链表中 并有对应的序号
    当有新节点时先判断其应在的位置,然后在链表通过序号中找到他前一个节点的句柄 
    然后用
    CTreeCtrl::InsertItem()时将最后一个参数hInsertAfter 设置为前一个节点的句柄就行了
    在链表中将其插入进去,前面的节点序号不变 后面的节点序号+1
      

  8.   


    在SortChildrenCB前遍历树,把每个节点的HTREEITEM句柄当作DWORD值SetItemData,并建立新ItemData到老ItemData的映射(比如用CMap),SortChildrenCB后恢复。当然,更好的办法是,能直接通过你设置的ItemData访问你的数据。例如,树中每个节点都对应一个结构,把该结构的内存指针(或者数组索引)当作ItemData。这样在回调函数中就可以直接根据你的数据进行比较了。
      

  9.   


    这个办法很好,我照做了,功能也实现了,但是在析构的时候出现问题了,我在析构函数中将我之前new出来的结构体都delete了,但是出错了,好像是我的树形控件对象已经被析构掉了。这是为什么,我应该在哪儿delete这些指针才行呢?
      

  10.   

    在析构里 先DeleteAllItems 在删链表试试
      

  11.   

    我的树形控件是从工具箱中拖过来的,不是自己create
      

  12.   


    CMonitorDlg::~CMonitorDlg()
    {
    DeleteAllItemData(m_hRoot);
    }void CMonitorDlg::DeleteAllItemData(HTREEITEM hTreeItem)
    {
    HTREEITEM hTreeItemNext = NULL, hTreeItemChild = NULL; if(hTreeItem == NULL)
    return;

    TREEITEMDATA *pTreeData = NULL;
    pTreeData = reinterpret_cast<TREEITEMDATA *>(m_MyTree.GetItemData(hTreeItem));
    if(pTreeData != NULL)
    {
    TRACE("data = %d\n", pTreeData->iData);
    delete pTreeData;
    pTreeData = NULL;
    } hTreeItemChild = m_MyTree.GetChildItem(hTreeItem);
    DeleteAllItemData(hTreeItemChild);

    hTreeItemNext = m_MyTree.GetNextItem(hTreeItem,TVGN_NEXT);
    DeleteAllItemData(hTreeItemNext);
    }上面就是我的析构,运行到
    pTreeData = reinterpret_cast<TREEITEMDATA *>(m_MyTree.GetItemData(hTreeItem));
    这句就报错了
      

  13.   

    真不好意思。。GetItemData()不是很理解。。
    CTreeCtrl::GetItemDataDWORD GetItemData( HTREEITEM hItem ) const;返回值:
    返回一个与由hItem指定的项关联的32位的应用程序指定值。参数: hItem 要获取其数据的项的句柄。  说明:
    此成员函数用来获取与指定项关联32位的应用程序指定值。
      

  14.   

    你是用SetItemData()设定的序号然后用GetItemData()获取的么
    我感觉你如果执行到
    pTreeData = reinterpret_cast<TREEITEMDATA *>(m_MyTree.GetItemData(hTreeItem));
    出错 应该是已经m_MyTree已经释放了
    你之前DeleteAllItems过么?
      

  15.   

    之前没有DeleteAllItems,
    看来只能把我自己写的DeleteAllItemData(m_hRoot);放到析构外面实现了