函数名称 | 功能 |
---|---|
CTreeCtrlDlg(CWnd* pParent = NULL); | 构造函数 |
void InitTreeFile(); | 初始化树形控件,若是复制或用其余对象初始化时须要调用 |
BOOL SetTreeRoot(const CString strPath); | 设置根目录 |
void SetUnwantedString(const std::vector
|
设置不想显示的子目录 |
BOOL SetAcceptMsgWnd(const HWND hWnd); | 设置接收消息的窗口句柄 |
CString GetPath(); | 获取当前被选中的目录 |
BOOL SetTreeImageList(CImageList * ImgList, int nImgList); | 设置当前控件目录图标 |
该函数是在经过一个对象来初始化另外一个对象或把一个对象赋值给另外一个对象后须要调用该函数,以初始化控件。函数
例如:this
CSelfUpdateTreeCtrl * pTreeFile; pTreeFile = new CSelfUpdateTreeCtrl(m_TreeFile); // m_TreeFile是另外一个控件 pTreeFile->Create(TVS_EDITLABELS | TVS_HASBUTTONS | WS_CHILD | WS_VISIBLE, rect, this, IDC_TREE_NODE); pTreeFile->ShowWindow(SW_SHOWNORMAL); pTreeFile->InitTreeFile(); // 这里调用初始化函数,初始化控件
设置控件根目录,在想要改变控件的根目录或者在建立对象的时候没有提供根目录的时候调用。返回值为BOOL型,若是返回值是TRUE,则成功。若是返回值是FALSE,则失败。code
例如:orm
CSelfUpdateTreeCtrl treeCtrl; treeCtrl.SetTreeRoot(_T("E:\\"));
不想有些目录出现,则可经过该函数设置一些要屏蔽的目录。对象
例如:继承
std::vector<CString> vecTemp; vecTemp.push_back(_T("二值图")); vecTemp.push_back(_T("缺陷大图")); vecTemp.push_back(_T("实时图")); vecTemp.push_back(_T("差影图")); m_TreeFile.SetTreeRoot(m_strGlobalPath); m_TreeFile.SetUnwantedString(vecTemp); // 设置不想显示文件夹的字符串
若是须要其余窗口响应控件的焦点变化的消息则须要调用该函数来设置接收消息的窗口。而响应的窗口须要响应相关的消息。其消息为:WM_SELFUPDATETREECTRL_SELCHANGED。返回值为BOOL型,若是返回值是TRUE,则成功。若是返回值是FALSE,则失败。递归
例如:索引
std::vector<CString> vecTemp; vecTemp.push_back(_T("二值图")); vecTemp.push_back(_T("缺陷大图")); vecTemp.push_back(_T("实时图")); vecTemp.push_back(_T("差影图")); m_TreeFile.SetTreeRoot(m_strGlobalPath); m_TreeFile.SetUnwantedString(vecTemp); m_TreeFile.SetAcceptMsgWnd(m_hWnd); // 设置接收消息的窗口
该函数是获取当前选中的节点的绝对路径。返回一个CString的,就是路径地址。图片
例如:ci
afx_msg LRESULT CBrowseDlg::OnSelfUpdateTreeMsg(WPARAM wParam,LPARAM lParam) { LoadInformation(m_TreeFile.GetPath()); return 0; }
设置控件中节点的图标。返回值为BOOL型,若是返回值是TRUE,则成功。若是返回值是FALSE,则失败。
HICON hIcon = theApp.LoadIcon(IDI_ICON_TREEFILE); CImageList imgList; imgList.Create(16, 16, ILC_COLOR32, 3, 3); for (int i = 0; i < 8; i++) { imgList.Add(hIcon); } m_TreeFile.SetTreeImageList(&imgList, LVSIL_NORMAL);
声明为类成员变量
// 在头文件中声明为类 CSelfUpdateTreeCtrl m_TreeFile;
// 初始化控件 std::vector<CString> vecTemp; vecTemp.push_back(_T("二值图")); vecTemp.push_back(_T("缺陷大图")); vecTemp.push_back(_T("实时图")); vecTemp.push_back(_T("差影图")); m_TreeFile.SetTreeRoot(m_strGlobalPath); m_TreeFile.SetUnwantedString(vecTemp); m_TreeFile.SetAcceptMsgWnd(m_hWnd); HICON hIcon = theApp.LoadIcon(IDI_ICON_TREEFILE); CImageList imgList; imgList.Create(16, 16, ILC_COLOR32, 3, 3); for (int i = 0; i < 8; i++) { imgList.Add(hIcon); } m_TreeFile.SetTreeImageList(&imgList, LVSIL_NORMAL);
CRect rect(300,0, 500,300); m_pTreeFile = new CSelfUpdateTreeCtrl(m_TreeFile); // 动态建立树形控件 m_pTreeFile->Create(TVS_EDITLABELS | TVS_HASBUTTONS | WS_CHILD | WS_VISIBLE, rect, this, IDC_TREE_NODE); m_pTreeFile->ShowWindow(SW_SHOWNORMAL); m_pTreeFile->InitTreeFile();
// 头文件 #pragma once #include <vector> // Tree结构 #define WM_SELFUPDATETREECTRL_SELCHANGED WM_USER + 779 // CSelfUpdateTreeCtrl class CSelfUpdateTreeCtrl : public CTreeCtrl { DECLARE_DYNAMIC(CSelfUpdateTreeCtrl) public: CSelfUpdateTreeCtrl(); CSelfUpdateTreeCtrl(CString strPath); virtual ~CSelfUpdateTreeCtrl(); CSelfUpdateTreeCtrl(CSelfUpdateTreeCtrl & ob); CSelfUpdateTreeCtrl & operator= (CSelfUpdateTreeCtrl & ob); protected: DECLARE_MESSAGE_MAP() private: CString m_strRoot; // 根目录 HWND m_hAcceptMessage; // 接收消息的窗口 std::vector<HTREEITEM> m_vecTreeTop; // 目录节点树,每个元素表明一个顶级目录 std::vector<HTREEITEM> m_vecHierarchy; // 目录节点用于遍历顶级目录下的子目录 std::vector<CString> m_vecUnwantedString; // 不想出如今树形结构上的目录名称列表 CImageList m_ImgList; // 目录树图标列表 int m_nImgList; // 初始化根目录 BOOL InitRootDirectory(); // 更新树节点 BOOL UpdateTreeNode(const unsigned long nIndex); // 判断当前节点级别 int JudgeFloor(); // 插入树节点 BOOL InsertTreeNode(const CString strRoot, const unsigned long nIndex); // 递归插入 BOOL InsertRecursion(const CString strRoot, int nFileNum, const unsigned long nIndex); // 拷贝图标列表数据 BOOL SetTreeImageList(CImageList * ImgList); public: // 初始化树形控件,若是复制或用其余对象初始化时须要调用 void InitTreeFile(); // 设置根目录 BOOL SetTreeRoot(const CString strPath); // 设置不想显示的目录 void SetUnwantedString(const std::vector<CString> vecStr); // 设置接收消息的窗口 BOOL SetAcceptMsgWnd(const HWND hWnd); // 获取当前目录 CString GetPath(); // 发送消息函数 afx_msg void OnTvnSelchanged(NMHDR * pNMHDR, LRESULT * pResult); // 设置图标列表 BOOL SetTreeImageList(CImageList * ImgList, int nImgList); };
// 源文件 // SelfUpdateTreeCtrl.cpp : 实现文件 // #include "stdafx.h" #include "SelfUpdateTreeCtrl.h" #include <algorithm> // CSelfUpdateTreeCtrl IMPLEMENT_DYNAMIC(CSelfUpdateTreeCtrl, CTreeCtrl) CSelfUpdateTreeCtrl::CSelfUpdateTreeCtrl() { m_strRoot = ""; m_hAcceptMessage = NULL; m_nImgList = LVSIL_NORMAL; } CSelfUpdateTreeCtrl::CSelfUpdateTreeCtrl(CString strPath) : m_strRoot(strPath) { m_hAcceptMessage = NULL; m_nImgList = LVSIL_NORMAL; InitRootDirectory(); } CSelfUpdateTreeCtrl::~CSelfUpdateTreeCtrl() { if ( NULL != m_ImgList.GetSafeHandle()) { m_ImgList.DeleteImageList(); ASSERT(m_ImgList.GetSafeHandle() == NULL); } } CSelfUpdateTreeCtrl::CSelfUpdateTreeCtrl(CSelfUpdateTreeCtrl & ob) { m_strRoot = ob.m_strRoot; m_hAcceptMessage = ob.m_hAcceptMessage; if (!m_vecTreeTop.empty()) { m_vecTreeTop.clear(); } if (!m_vecHierarchy.empty()) { m_vecHierarchy.clear(); } if (!m_vecUnwantedString.empty()) { m_vecUnwantedString.clear(); } m_vecTreeTop = ob.m_vecTreeTop; m_vecHierarchy = ob.m_vecHierarchy; m_vecUnwantedString = ob.m_vecUnwantedString; //图标列表 m_nImgList = ob.m_nImgList; SetTreeImageList( &(ob.m_ImgList)); } CSelfUpdateTreeCtrl & CSelfUpdateTreeCtrl::operator= (CSelfUpdateTreeCtrl & ob) { //CTreeCtrl::operator= (ob); if (this == &ob) return * this; m_strRoot = ob.m_strRoot; m_hAcceptMessage = ob.m_hAcceptMessage; if (!m_vecTreeTop.empty()) { m_vecTreeTop.clear(); } if (!m_vecHierarchy.empty()) { m_vecHierarchy.clear(); } if (!m_vecUnwantedString.empty()) { m_vecUnwantedString.clear(); } m_vecTreeTop = ob.m_vecTreeTop; m_vecHierarchy = ob.m_vecHierarchy; m_vecUnwantedString = ob.m_vecUnwantedString; // 图标列表 m_nImgList = ob.m_nImgList; if (m_ImgList.GetSafeHandle()) { m_ImgList.DeleteImageList(); ASSERT(m_ImgList.GetSafeHandle() == NULL); } SetTreeImageList(&(ob.m_ImgList)); return *this; } BEGIN_MESSAGE_MAP(CSelfUpdateTreeCtrl, CTreeCtrl) ON_NOTIFY_REFLECT(TVN_SELCHANGED, &CSelfUpdateTreeCtrl::OnTvnSelchanged) END_MESSAGE_MAP() // CSelfUpdateTreeCtrl 消息处理程序 BOOL CSelfUpdateTreeCtrl::SetTreeRoot(CString strPath) { m_strRoot = strPath; return InitRootDirectory(); } BOOL CSelfUpdateTreeCtrl::InitRootDirectory() { if ("" == m_strRoot) { return FALSE; } if (!m_vecTreeTop.empty()) { m_vecTreeTop.clear(); } CFileFind file; CString strDirectory = m_strRoot; if ( strDirectory.Right(1) != "\\" ) { strDirectory += _T("\\"); } strDirectory += _T("*.*"); BOOL bRet = file.FindFile(strDirectory); unsigned long ulNum = 0;// 给每一个结点设置索引号 while(bRet) { bRet = file.FindNextFile(); // 是否有下一个目录 if (file.IsDirectory() && !file.IsDots()) { CString strPath = file.GetFilePath(); CString strTitle = strPath.Right(strPath.GetLength()-strPath.ReverseFind('\\')-1); HTREEITEM hItem = InsertItem(strTitle, 0, 0, NULL); m_vecTreeTop.push_back(hItem); SetItemData(hItem, ulNum); ulNum++; } } file.Close(); return TRUE; } void CSelfUpdateTreeCtrl::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult) { LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 // 获取当前选中节点深度 int nFloor = JudgeFloor(); // 更新当前目录 if ( 0 == nFloor && !ItemHasChildren(GetSelectedItem())) { unsigned long ulNum = GetItemData(GetSelectedItem()); UpdateTreeNode(ulNum); } else { if (m_hAcceptMessage) { ::PostMessage(m_hAcceptMessage, WM_SELFUPDATETREECTRL_SELCHANGED, 0, 0); } } *pResult = 0; } int CSelfUpdateTreeCtrl::JudgeFloor() { int nDepth = 0; HTREEITEM hCurrentNode = GetSelectedItem(); while ( (hCurrentNode = GetParentItem(hCurrentNode)) != NULL) { nDepth++; } return nDepth; } BOOL CSelfUpdateTreeCtrl::UpdateTreeNode(unsigned long nIndex) { // 调用插入节点函数 return InsertTreeNode(GetPath(), nIndex); } BOOL CSelfUpdateTreeCtrl::InsertTreeNode(CString strRoot, unsigned long nIndex) { if ( "" == strRoot || nIndex >= m_vecTreeTop.size()) { return FALSE; } BOOL bRet = InsertRecursion(strRoot, 0, nIndex); m_vecHierarchy.clear(); return bRet; } BOOL CSelfUpdateTreeCtrl::InsertRecursion(CString strRoot, int nFileNum, unsigned long nIndex) { nFileNum++;//这个必定要放在switch以前,不能放在下面 CFileFind file; CString strDirectory = strRoot; if ( strDirectory.Right(1) != "\\" ) { strDirectory += _T("\\"); } strDirectory += _T("*.*"); BOOL bRet = file.FindFile(strDirectory); while(bRet) { bRet = file.FindNextFile(); // 是否有下一个目录 if (file.IsDirectory() && !file.IsDots()) { CString strPath = file.GetFilePath(); CString strTitle = strPath.Right(strPath.GetLength()-strPath.ReverseFind('\\')-1); if(std::find(m_vecUnwantedString.begin(), m_vecUnwantedString.end(), strTitle) != m_vecUnwantedString.end()) { continue; } switch( nFileNum ) { case 1: if (m_vecHierarchy.empty()) { m_vecHierarchy.push_back(InsertItem(strTitle, nFileNum, nFileNum, m_vecTreeTop[nIndex])); } else { m_vecHierarchy[nFileNum - 1] = InsertItem(strTitle, nFileNum, nFileNum,m_vecTreeTop[nIndex]); } break; default: if ( m_vecHierarchy.size() <= nFileNum - 1 ) { m_vecHierarchy.push_back(InsertItem(strTitle, nFileNum, nFileNum,m_vecHierarchy[nFileNum - 2])); } else { m_vecHierarchy[nFileNum - 1] = InsertItem(strTitle, nFileNum, nFileNum,m_vecHierarchy[nFileNum - 2]); } break; } InsertRecursion(strPath, nFileNum, nIndex);//递归遍历子目录 } else if( !file.IsDirectory() && !file.IsDots() )//若是不是一个目录,而且也不是当前目录 { ;//暂时不处理其余类型的图片 } }//是否找到文件 file.Close(); return TRUE; } void CSelfUpdateTreeCtrl::SetUnwantedString(std::vector<CString> vecStr) { m_vecUnwantedString = vecStr; } BOOL CSelfUpdateTreeCtrl::SetAcceptMsgWnd(HWND hWnd) { if (hWnd) { m_hAcceptMessage = hWnd; return TRUE; } else { return FALSE; } } CString CSelfUpdateTreeCtrl::GetPath() { HTREEITEM CurrentNode = GetSelectedItem(); HTREEITEM ParentNode = GetParentItem(CurrentNode); CString strPath = GetItemText(ParentNode); CString strSelf = GetItemText(CurrentNode); if ("" == strPath) { strPath += strSelf+_T("\\"); } else { strPath += _T("\\") + strSelf+_T("\\"); } while((ParentNode = GetParentItem(ParentNode))!=NULL) { CString strTemp = GetItemText(ParentNode); strPath = strTemp + _T("\\") + strPath; } strPath = m_strRoot + _T("\\") + strPath; return strPath; } BOOL CSelfUpdateTreeCtrl::SetTreeImageList(CImageList * ImgList, int nImgList) { if ((NULL == ImgList->GetSafeHandle()) || (ImgList == &m_ImgList)) { return FALSE; } if ( m_ImgList.GetSafeHandle() ) { m_ImgList.DeleteImageList(); ASSERT( m_ImgList.GetSafeHandle() == NULL); } m_ImgList.Create(ImgList); m_nImgList = nImgList; SetImageList(&m_ImgList, m_nImgList); return TRUE; } BOOL CSelfUpdateTreeCtrl::SetTreeImageList(CImageList * ImgList) { if ((NULL == ImgList->GetSafeHandle()) || (ImgList == &m_ImgList)) { return FALSE; } if ( m_ImgList.GetSafeHandle() ) { m_ImgList.DeleteImageList(); ASSERT( m_ImgList.GetSafeHandle() == NULL); } m_ImgList.Create(ImgList); return TRUE; } void CSelfUpdateTreeCtrl::InitTreeFile() { if (!m_vecTreeTop.empty()) { m_vecTreeTop.clear(); DeleteAllItems(); } SetImageList(&m_ImgList, m_nImgList); InitRootDirectory(); }
该类继承自类CTreeCtrl,重载了“=”操做符和拷贝构造函数,能够直接把一个对象赋值给另外一个对象,或者用一个对象初始化另外一个对象。可是以后须要调用InitTreeFile()函数。
这里是采用了缓加载目录的方法,当初始化后会只加载顶级目录,子目录是没有加载的。这样能够避免当目录过多的时候致使加载时间过长的现象。子目录是当焦点转移到顶级目录的时候才加载相关目录下面的子目录。
以下图: