开发类似ftp客户端的这种软件,需要对每个磁盘下的文件目录进行罗列并显示。方便文件的上传、下载等。就如同我们打开每个磁盘所显示的那样,罗列了你这个磁盘目录下的所有文件夹和文件。
那我们在自己的程序中如何做到这样呢?
主要用到两个方面的知识:CFileFind和list control的使用。关于这两方面的知识,不是我此篇博文的目的,况且我就是一个菜鸟,我只是贴两篇详细讲这个的博文。Vc控件用法总结之List Control; MFC中ListControl控件的使用 ;CFileFind类学习 .
那么接下来开始操作:
1、首先我们肯定是要在对话框中的某个位置拖放一个List控件,并关联变量CListCtrl m_listlocal。
2、我们需要给list添加列(比如三列,分别是文件名,日期,字节数)
我们可以在OninitDialog()函数中实现。
//获得控件扩展属性
DWORD dwStyle = m_listlocal.GetExtendedStyle();
//选中某行使整行高亮(只适用与report风格的listctrl)
dwStyle |= LVS_EX_FULLROWSELECT;
//网格线(只适用与report风格的listctrl)
dwStyle |= LVS_EX_GRIDLINES;
//设置控件扩展属性
m_listlocal.SetExtendedStyle(dwStyle);
m_listlocal.InsertColumn(0, "文件名",LVCFMT_LEFT,100);
m_listlocal.InsertColumn(1,"日期",LVCFMT_LEFT,100);
m_listlocal.InsertColumn(2,"字节数",LVCFMT_LEFT,100);
3、完成第2步之后运行就会发现list控件具有三列了,分别是文件名,日期,字节数。那么关键的一步来了,如何罗列给定磁盘的文件目录呢?
直接上代码:
void CFTPCilentDlg::locallistdir(CString strdir) //列出文件目录
{
//strdir表示C:、D:、E:...
CFileFind finddlg;
CString szdir=strdir;
CString strname;
CString strtime;
ULONGLONG byte;
CString strbyte;
CTime refTime;
int i=0;
SHFILEINFO finfo;
CListCtrl* plst_ctl=(CListCtrl*)GetDlgItem(IDC_LISTlocal);//IDC_LIST1为CListCtrl控件的ID
//添加图标(将图标存放在CImageList对象中,并与CListCrtl控件相关联)
//m_imagelist_b.Create(32,32,ILC_COLOR32|ILC_MASK ,0,0);//大图标
m_imagelist_s=new CImageList();
m_imagelist_s->Create(16,16,ILC_COLOR32|ILC_MASK ,0,0);//小图标
//plst_ctl->SetImageList(&m_imagelist_b,LVSIL_NORMAL);//大图标
plst_ctl->SetImageList(m_imagelist_s,LVSIL_SMALL);
if(szdir.Right(1)!= "\\")
szdir+= "\\"; //千万注意此处不能有空格,妈的,废了老子2个小时来调试
szdir+= "*.*"; //同上,同上,同上
BOOL res=finddlg.FindFile(szdir);
while(res)
{
res=finddlg.FindNextFile();
if(finddlg.IsDots()) //找到.文件
{
//MessageBox("zhaodaole");
strname.Format("%s",finddlg.GetFileName());
if (strname.Compare("..")==0) //找到上层目录
{
//获取文件信息,主要图标icon
SHGetFileInfo(finddlg.GetFilePath(),0,&finfo,sizeof(finfo),SHGFI_ICON );
//添加文件项目和图标
//m_imagelist_b.Add(finfo.hIcon);//向ImageList里添加图标资源
int m=plst_ctl->InsertItem(0,finddlg.GetFileName(), m_imagelist_s->Add(finfo.hIcon));//空出第一行
}
}
else if(finddlg.IsDirectory()&&!finddlg.IsDots()) //找到目录(文件夹)并且不是隐藏文件....xxx
{
//locallistdir(finddlg.GetFilePath());
strname.Format("%s",finddlg.GetFileName());
if (finddlg.GetLastAccessTime(refTime))
{
strtime=refTime.Format("%d/%m/%y");
}
// int m=m_listlocal.InsertItem(i,strname); 这句和下面的plst_ctl->InsertItem(i,finddlg.GetFileName(...重复了
//获取文件信息,主要图标icon
SHGetFileInfo(finddlg.GetFilePath(),0,&finfo,sizeof(finfo),SHGFI_ICON );
//添加文件项目和图标
//m_imagelist_b.Add(finfo.hIcon);//向ImageList里添加图标资源
int m=plst_ctl->InsertItem(1,finddlg.GetFileName(), m_imagelist_s->Add(finfo.hIcon));
m_listlocal.SetItemText(m,1,strtime);
m_listlocal.SetItemText(m,2,_T("*"));
}
else //!finddlg.IsDirectory()&&!finddlg.IsDots() //不是目录也不是隐藏文件,即找到文件
{
strname.Format("%s",finddlg.GetFileName());
if (finddlg.GetLastAccessTime(refTime))
{
strtime=refTime.Format("%d/%m/%y");
}
byte=finddlg.GetLength(); //此处要注意溢出,害惨我了
byte/=1024;
float MByte=(float)byte/1024;
if (MByte>=1.0)
{
char *s=new char[256];
memset(s,0,256);
sprintf(s,"%.1f",MByte);
strbyte.Format(_T("%s"),s);
strbyte+="MB";
delete s;
}
else
{
strbyte.Format(_T("%d"),byte); //还有此处的类型转换,不能用%s,而要用%d.
strbyte+="KB";
}
// int m=m_listlocal.InsertItem(i,strname);
//获取文件信息,主要图标icon
SHGetFileInfo(finddlg.GetFilePath(),0,&finfo,sizeof(finfo),SHGFI_ICON );
//添加文件项目和图标
//m_imagelist_b.Add(finfo.hIcon);//向ImageList里添加图标资源
int m=plst_ctl->InsertItem(1,finddlg.GetFileName(), m_imagelist_s->Add(finfo.hIcon));
m_listlocal.SetItemText(m,1,strtime);
m_listlocal.SetItemText(m,2,strbyte);
}
}
finddlg.Close();
}
由于我是直接从我的工程当中复制了代码,所以有些语句跟这篇博文的主题并无关系,如果需要使用,需要删除一些语句。
那么我简要介绍一下代码:核心代码在while()循环里边,通过函数IsDots()和IsDirectory()对文件类型进行判断,找到一个文件,再接着找下一个文件,FindNextFile()和FindFile()两个函数进行查找,如果找到,则返回值非零,否则为零。其实查找的过程很简单,代码也很容易理解。具体涉及到对list控件的操作是这几行代码:
int m=plst_ctl->InsertItem(1,finddlg.GetFileName(), m_imagelist_s->Add(finfo.hIcon));
m_listlocal.SetItemText(m,1,strtime);
m_listlocal.SetItemText(m,2,_T("*"));
其中有几行代码是:
CListCtrl* plst_ctl=(CListCtrl*)GetDlgItem(IDC_LISTlocal);//IDC_LIST1为CListCtrl控件的ID
//添加图标(将图标存放在CImageList对象中,并与CListCrtl控件相关联)
//m_imagelist_b.Create(32,32,ILC_COLOR32|ILC_MASK ,0,0);//大图标
m_imagelist_s=new CImageList();
m_imagelist_s->Create(16,16,ILC_COLOR32|ILC_MASK ,0,0);//小图标
//plst_ctl->SetImageList(&m_imagelist_b,LVSIL_NORMAL);//大图标
plst_ctl->SetImageList(m_imagelist_s,LVSIL_SMALL);
主要的功能是获取文件目录的图标,然后添加在List控件的第一列中,方便我们认识这个文件的类型。具体用法,我就不班门弄斧了,大家自行百度。
好了,基本的用法就如上所示,可以实现下图的样子:
关于list控件的其他使用,比如响应鼠标左键单击,右键单击等,我在后边的博客会简要记录一下。
ok,到此!
拙见,小记!