您的位置:首页 > 其它

MFC里的CTreeCtrl控件和CListCtrl控件的结合使用之一

2015-11-15 21:22 1301 查看
不想过于啰嗦,所以直接进入主题。

效果:点击CTreeCtrl控件的文件时,CListCtrl控件显示里面的文件图标和文件名

思路:先显示树形控件里的文件。首先获取文件的路径,通过文件路径名的特性C:\Test\test1\test.txt从根节点递归插入,根节点是C:,父节点是Test,子节点是test1,孙子节点是test.txt.可以把文件分级插入相应的节点

贴代码:这是一个自己写的函数,接受两个参数,一个是根节点的路径,另一个就是根节点的句柄。

以下代码会用到的变量:

CTreeCtrl m_itemTree;               //树形控件
CListCtrl m_listBox;
CImageList m_imageList;             //树形控件的图像序列
CImageList m_imageListBox;          //listBox的图像序列
CString m_CurTreeDir;           //保存节点的当前路径


void CItemdlg::ShowFiles(CString str_Dir, HTREEITEM treeRoot)
{
CFileFind myfileFind;

HTREEITEM treeTemp;     //临时树节点句柄,用于记录返回的节点
if (str_Dir.Right(1) != "\\")                   //判断输入目录最后是否存在"\\",没有就补充,其实是\但是编译器把它当转义字符用了,所以要\\,
str_Dir += "\\";
str_Dir += "*.*";
BOOL bRes = myfileFind.FindFile(str_Dir);
while (bRes)
{
treeTemp = treeRoot;
bRes = myfileFind.FindNextFile();
/*说明:IsDirectory表明这是一个目录,isDots表明这个是‘.’或者‘..’而这两个东西虽然是目录,但是一个表明这个目录本身,一个代表上层目录(但是根目录下面..也是本身)*/
if (myfileFind.IsDirectory() && !myfileFind.IsDots())           //目录是文件夹
{
CString strFilePath = myfileFind.GetFilePath();             //得到路径,作为递归调用的开始
CString strFileTitle = myfileFind.GetFileName();            //得到目录名,作为树控的节点
treeTemp = m_itemTree.InsertItem((LPCTSTR)strFileTitle,1,1,treeRoot,TVI_LAST);
/*第一个参数是一个包含项的文本的字符串的地址,第二个参数是项的图像在tree view控件的图像列表中的索引,
第三个参数是项的被选择图像在tree view控件的图像列表中的索引,第四个参数是要被插入的项的父项的句柄,第五个参数是新项要被插入其后的项的句柄*/
ShowFiles(strFilePath,treeTemp);  //递归的开始
}
else if( !myfileFind.IsDirectory() && !myfileFind.IsDots() )        //如果是文件
{
CString strFilePath = myfileFind.GetFilePath();             //得到路径,作为递归调用的开始
CString strFileTitle = myfileFind.GetFileName();            //得到目录名,作为树控的节点
m_itemTree.InsertItem((LPCTSTR)
strFilePath,2,2,treeRoot,TVI_LAST);
}
else
{
continue;
}
}
myfileFind.Close();    //关闭
}


这里有必要说明这个类CFileFind:调用此成员函数打开一个文件查找。

当调用FindFile开始查找后,调用FindNextFile获取下一个文件。

你必须在调用下列属性函数之前调用一次FindNextFile: · GetCreationTime

· GetFileName

· GetFileTitle

· GetFilePath

· GetFileURL

· GetLastAccessTime

· GetLastWriteTime

· GetLength

· GetRoot

至于为什么,当然是自己动手丰衣足食了。

再然后就是一个中间函数,以为需要获取选中节点的路径,得从下往上递归。

代码:

CString CItemdlg::GetFullPath(HTREEITEM hCurItem)
{
CString strTemp;
CString strReturn = "";
while (hCurItem != m_itemTree.GetRootItem())        //因为是向上递归,所以判断条件是:不是根节点就一直while
{
strTemp = m_itemTree.GetItemText(hCurItem);     //得到文件名
if (strTemp.Right(1) != "\\")
strTemp += "\\";
strReturn =strTemp + strReturn ;                //注意两个字符串变量不要反了,前面的必须是文件的上一级的路径名
hCurItem = m_itemTree.GetParentItem(hCurItem);
}
return strReturn;
}

然后就是CListCtrl控件的代码了
我是把它放在一个消息函数里了,TVN_SELCHANGED,他是指示用户单击了鼠标左键
代码如下:


void CItemdlg::OnTvnSelchangedItemTree(NMHDR *pNMHDR, LRESULT *pResult)
{
//LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
/*
CString treeRootText;       // 树节点的标签文本字符串
HTREEITEM hItem;            //当前节点
hItem = m_itemTree.GetSelectedItem();       //获得选中项目树形控件的句柄
treeRootText = m_itemTree.GetItemText(hItem);       //获得选中节点的标签
SetDlgItemText(IDC_ITEM_EDIT, treeRootText);        //把所获得的标签传给项目EDIT控件显示出来
*/
m_listBox.DeleteAllItems();                     //删除列表视图控件中所有的项
HTREEITEM hItem;
hItem = m_itemTree.GetSelectedItem();           //获得鼠标所选的节点句柄
if (hItem == m_itemTree.GetRootItem())          //如果是根节点直接返回
return;
CString strPath = GetFullPath(hItem);               //得到选中节点的路径
if (strPath.Right(1) != "\\")
strPath += "\\";
strPath += "*.*";
CFileFind myFileFind;
CString rootPath = "D:\\C++Code\\";         //加上根路径
strPath = rootPath + strPath;
BOOL bRes = myFileFind.FindFile(strPath);
while (bRes)
{
bRes = myFileFind.FindNextFile();
if (myFileFind.IsDirectory() && !myFileFind.IsDots())           //如果是文件夹
{
SHFILEINFO info;
CString temp = strPath;
int idex = temp.Find("*.*");
temp.Delete(idex,3);
SHGetFileInfo(temp + myFileFind.GetFileName(), 0, &info, sizeof(&info), SHGFI_DISPLAYNAME | SHGFI_ICON);
int i = m_imageListBox.Add(info.hIcon);
m_listBox.InsertItem(i,info.szDisplayName,i);
}
}
myFileFind.Close();
}


还有图标的插入,都把他们放到对话框程序的初始化函数里就OK了

BOOL CItemdlg::OnInitDialog()
{
CDialog::OnInitDialog();
//对ListBox的图标进行初始化
HICON hIconlistBox;
hIconlistBox = AfxGetApp()->LoadIcon(IDI_SONFILE_ICON);
m_imageListBox.Create(32, 32, ILC_COLOR32 | ILC_MASK, 1, 1);                //创建图像序列CImageList对象
m_imageListBox.Add(hIconlistBox);
m_listBox.SetImageList(&m_imageListBox, LVSIL_NORMAL);
HTREEITEM tree_root;
HICON hIcon[3];      // 图标句柄数组
hIcon[0] = AfxGetApp()->LoadIcon(IDI_FILE_ICON);        //加载图标
hIcon[1] = AfxGetApp()->LoadIcon(IDI_FILE_ICON);        //加载图标
hIcon[2] = AfxGetApp()->LoadIcon(IDI_SONFILE_ICON);     //加载图标
m_imageList.Create(16, 16, ILC_COLOR32 | ILC_MASK, 3, 3);               //创建图像序列CImageList对象
//以上函数第四个参数是创建的时候初始化包含的位图数目;第五个参数是说你增加新的位图的时候,超过了预分配的大小后每次新分配的位图数目。
for (int i = 0; i < 3; i++)
{
m_imageList.Add(hIcon[i]);                      //将图标添加到图像序列
}
m_itemTree.SetImageList(&m_imageList, TVSIL_NORMAL);     // 为树形控件设置图像序列
tree_root = m_itemTree.InsertItem(_T("项目"), 0, 0);  //设置根节点
m_itemTree.SetTextColor(RGB(54,54,54));             //设置文件名的颜色
ShowFiles(_T("D:\\C++Code"), tree_root);
/*
HTREEITEM hRoot;     // 树的根节点的句柄
HTREEITEM hCataItem; // 可表示任一项目名节点的句柄
HTREEITEM hArtItem;  // 可表示任一文件节点的句柄
hIcon[0] = AfxGetApp()->LoadIcon(IDI_FILE_ICON);        //加载图标
hIcon[1] = AfxGetApp()->LoadIcon(IDI_FILE_ICON);        //加载图标
hIcon[2] = AfxGetApp()->LoadIcon(IDI_SONFILE_ICON);     //加载图标

m_imageList.Create(32,32, ILC_COLOR32 | ILC_MASK,3,3);              //创建图像序列CImageList对象
//以上函数第四个参数是创建的时候初始化包含的位图数目;第五个参数是说你增加新的位图的时候,超过了预分配的大小后每次新分配的位图数目。
for (int i = 0; i < 3; i++)
{
m_imageList.Add(hIcon[i]);                      //将图标添加到图像序列
}

m_itemTree.SetImageList(&m_imageList, TVSIL_NORMAL);     // 为树形控件设置图像序列

hRoot = m_itemTree.InsertItem(_T("项目"),0,0);             // 插入根节点

return TRUE;
}


这样它们就结合使用起来了,后续可以添加鼠标的各种点击事件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: