Win32 SDK 下的TreeCtrl控件的封装

自己照着MFC封装,半月前封装了一半,碰到问题就放下了,今天终于封装好了.

[Ctree.h]文件

#pragma once
#include <windows.h>
#include <commctrl.h>


struct MTVINSERTSTRUCT
{
    TVINSERTSTRUCT tvInsert;
    TCHAR strMid[2500];
};

class CTree
{
public:
    CTree();
    ~CTree();

    HWND m_hWnd;
public:
    //获得树控件的句柄
    BOOL GetHwnd(HWND _pHwnd, UINT _idd);

    //插入树节点
    HTREEITEM InsertItem(LPTVINSERTSTRUCT lpInsertStruct);
    HTREEITEM InsertItem(LPCTSTR lpszItem, int nImage, int nSelectedImage,
        HTREEITEM hParent, HTREEITEM hInsertAfter);

    //获得选中节点的句柄
    HTREEITEM GetSelectedItem()const;
    //删除选中节点
    BOOL DeleteItem(HTREEITEM hItem);
    //删除所有的节点项
    BOOL DeleteAllItem();
    //设置节点附加的32位数据
    BOOL SetItemData(HTREEITEM hItem, DWORD dwData);
    //设置节点项数据
    BOOL SetItem(TVITEM *pItem);
    BOOL SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage,
        UINT nState, UINT nStateMask, LPARAM lParam);
    //获得选中节点项附加的32位数据
    DWORD GetItemData(HTREEITEM hItem)const;
    //获得选中节点项的显示的名称
    TCHAR* GetItemText(HTREEITEM hItem)const;
    //获得选中节点项的图标索引值
    BOOL GetItemImage(HTREEITEM hItem, int &nImage, int &nSelectedImage)const;
    //获得选中节点项的展开状态
    BOOL GetItemState(HTREEITEM hItem, UINT nStateMask) const;
};

 

[Ctree.cpp]文件

#include "CTree.h"
#include <tchar.h>
#include <atlchecked.h>

#pragma region MY_CtreeCtrl_Class


CTree::CTree()
{
    m_hWnd = NULL;

}

CTree::~CTree()
{

}

BOOL CTree::GetHwnd(HWND _pHwnd, UINT _idd)
{
    m_hWnd = GetDlgItem(_pHwnd, _idd);
    if (m_hWnd)
    {
        return TRUE;
    }
    return FALSE;
}

HTREEITEM CTree::InsertItem(LPTVINSERTSTRUCT lpInsertStruct)
{
    IsWindow(m_hWnd);
    return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct);
}

HTREEITEM CTree::InsertItem(LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter)
{
    IsWindow(m_hWnd);
    TVINSERTSTRUCT lpInsert;
    lpInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
    lpInsert.item.iImage = nImage;
    lpInsert.item.iSelectedImage = nSelectedImage;
    lpInsert.item.pszText = (LPWSTR)lpszItem;

    if (NULL == hParent)
        hParent = TVI_ROOT;
    lpInsert.hParent = hParent;

    lpInsert.hInsertAfter = hInsertAfter;
    
    return InsertItem(&lpInsert);
}

HTREEITEM CTree::GetSelectedItem() const
{
    IsWindow(m_hWnd);
    return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CARET, 0);
}

BOOL CTree::DeleteItem(HTREEITEM hItem)
{
    IsWindow(m_hWnd);
    return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)hItem);
}

BOOL CTree::DeleteAllItem()
{
    IsWindow(m_hWnd);
    return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
}
//32位系统可用
BOOL CTree::SetItemData(HTREEITEM hItem, DWORD dwData)
{
    IsWindow(m_hWnd);

    return SetItem(hItem, TVIF_PARAM, NULL, 0, 0, 0, 0, (LPARAM)dwData);
}
//64位系统上要用LPARAM 用DWORD要被截断
//***********************************************************************************
BOOL AfxCTreeCtrl::SetItemData(HTREEITEM hItem, LPARAM dwData)

{
  ASSERT(IsWindow(m_hWnd));
  return SetItem(hItem, TVIF_PARAM, NULL, 0, 0, 0, 0, (LPARAM)dwData);
}

//***********************************************************************************
BOOL CTree::SetItem(TVITEM
* pItem) { IsWindow(m_hWnd); return (BOOL)SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)pItem); } BOOL CTree::SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam) { IsWindow(m_hWnd); TVITEM item; item.hItem = hItem; item.mask = nMask; item.pszText = (LPTSTR)lpszItem; item.iImage = nImage; item.iSelectedImage = nSelectedImage; item.state = nState; item.stateMask = nStateMask; item.lParam = lParam; return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item); } //32位系统可用 DWORD CTree::GetItemData(HTREEITEM hItem) const { IsWindow(m_hWnd); if (NULL == hItem) return 0; TVITEM item; item.hItem = hItem; item.mask = TVIF_PARAM; ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); return item.lParam; } //64位系统用

LPARAM AfxCTreeCtrl::GetItemData(HTREEITEM hItem) const
{
  ASSERT(IsWindow(m_hWnd));
  TVITEM item;
  item.hItem = hItem;
  item.mask = TVIF_PARAM;
  ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);

  return (LPARAM)item.lParam;
}

 


TCHAR* CTree::GetItemText(HTREEITEM hItem) const
{
    IsWindow(m_hWnd);
    TCHAR* str = new TCHAR[128];
    TVITEM item;
    item.hItem = hItem;
    item.mask = TVIF_TEXT;
    item.pszText = str;
    item.cchTextMax = 128;
    
    ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
        
    return str;
}

BOOL CTree::GetItemImage(HTREEITEM hItem, int &nImage, int &nSelectedImage) const
{
    IsWindow(m_hWnd);
    TVITEM item = { 0 };
    item.hItem = hItem;
    item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
    BOOL bRes = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
    if (bRes)
    {
        nImage = item.iImage;
        nSelectedImage = item.iSelectedImage;
    }
    return bRes;
}

BOOL CTree::GetItemState(HTREEITEM hItem, UINT nStateMask) const
{
    IsWindow(m_hWnd);
    TVITEM item = { 0 };
    item.hItem = hItem;
    item.mask = TVIF_STATE;
    item.stateMask = nStateMask;
    item.state = 0;
    ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
    return item.state;
}

#pragma endregion MY_CtreeCtrl_Class

 

[test.cpp]中测试

 

HTREEITEM hItem = m_tree.GetSelectedItem();
            //TVITEM tvi;
            //TCHAR szName[20] = { 0 };
            ////LPARAM lp = 0;
            //tvi.mask = TVIF_TEXT | TVIF_PARAM;
            //tvi.hItem = hItem;
            //tvi.pszText = szName;
            //tvi.cchTextMax = sizeof(szName);
            ////tvi.lParam = lp;
            //TreeView_GetItem(m_tree.m_hWnd, &tvi);
            //Stu *pstu = (Stu*)tvi.lParam;

            //获得选中节点的附加(由SetItemData设置的)数据
            /*Stu* pstu = (Stu*)m_tree.GetItemData(hItem);
            TCHAR *pch = (TCHAR*)m_tree.GetItemData(hItem);*/

//上次在封装这附加数据的时候碰到了问题.
在设置的时候:

TCHAR *pch = new TCHAR;
pch=mid;//mid为要设置的附加数据,类型为TCHAR
m_tree.SetItemData(nItem, (DWORD)pch);

 

就一直取不出来要的数据,就放下了.今天来看的时候才发现

TCHAR *pch = new TCHAR[128];
_tcscpy_s(pch, 128, mid);
m_tree.SetItemData(nItem, (DWORD)pch);

我用结构体指针为附加数据时,又能正确取出数据.就有点晕菜了,最后才发现.

TCHAR new出来时没给定大小.

 

正确代码为:

TCHAR *pch = new TCHAR[128];
_tcscpy_s(pch, 128, mid);
m_tree.SetItemData(nItem, (DWORD)pch);


//获得选中节点的Text /*TCHAR *pch = m_tree.GetItemText(hItem); MessageBox(NULL, pch, TEXT("123"), MB_OK);*/ //获得选中节点的图标的索引 /*int nImate, nSelectedImage; m_tree.GetItemImage(hItem, nImate, nSelectedImage);*/ //获得选中节点是否展开,返回0为未展开,非0为展开状态 //UINT n = m_tree.GetItemState(hItem, TVIS_EXPANDED); BOOL m = m_tree.GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED;

 释放节点附加数据内存

//5.附加内存的释放
//在子控件通知消息中捕获TVN_DELETEITEM消息
NMHDR *pNMHDR = (NMHDR*)lParam;
    if (pNMHDR->idFrom == IDC_TREE1 && pNMHDR->code==TVN_DELETEITEM)
    {
        NMTREEVIEW *pnmTV = (NMTREEVIEW*)lParam;
        HTREEITEM hSelItem = pnmTV-> itemNew.hItem;    //从lParam参数中获得选中项的句柄
        //释放节点附加数据内存
        TVITEM item = pnmTV->itemOld;
        if (item.lParam != 0)
        {
            delete (TCHAR*)item.lParam;//删除的数据类型要和前面添加时你附加的数据类型一样,
        }

    }

 

posted @ 2020-10-11 01:10  初吻给了烟灬  阅读(274)  评论(3编辑  收藏  举报