学了几天的VC++.Net终于有了这一个习作,我很喜欢用PDA看小说,有时候下载下来的网页就需要批量改名,一直用国华的这个,感觉还算好用,这两天学了VC++就寻思着仿写一个。昨晚搞定。
Version 1.5
在这里记下几个开发中的问题。
第一个问题:目录树
国华的那个目录树很难看,不是XP风格,我自己写目录树的时候查了好多地方终于下载到一个DirTreeDemo有人家写好的CDirTreeCtrl,继承自CTreeCtrl很不错,可惜注释有很多地方是德语,偶看不懂,研究了好久,终于能用了。主要接口如下:
public:
BOOL SetSelPath( LPCTSTR strPath );//设置当前目录为strPath
CString GetFullPath( HTREEITEM hItem );//得到hItem的路径
LPCTSTR GetSubPath( LPCTSTR strPath );//(没用到,没研究,汗)
BOOL DisplayTree( LPCTSTR strRoot, BOOL bFiles = FALSE );//显示整个目录树strRoot为根目录输入NULL则显示本机所有Drives,bFiles为TRUE则显示文件否则只显示目录。
主要文件四个:DirTreeCtrl.H,DirTreeCtrl.CPP,SortStringArray.CPP,SortStringArray.H
第二个问题:ComboBox用于用户输入或选择扩展名
我靠,这个东东居然搞了我好几个小时,真是晕死。本以为ComboBox的Edit 和List的句柄很好拿结果我用COMBOBOXINFO结构vs居然告诉我未声明的标识符,我明明Include了winuser.h和windows.h了啊。最后还是用GetWindowText解决问题,ComboBox的Edit和List的句柄就是拿不到,哪位大虾指教一下。
第三个问题:ListBox的横向滚动条
直接从MSDN拷贝的代码,效率不是最好,但是目前这个程序里比较够用。
void CMyRenamerDlg::ListHScroll(void)
{
CListBox* pmyListBox;//指向自己的ListBox的指针
pmyListBox = &m_FileList;
// Find the longest string in the list box.
CString str;
CSize sz;
int dx = 0;
TEXTMETRIC tm;
CDC* pDC = pmyListBox->GetDC();
CFont* pFont = pmyListBox->GetFont();
// Select the listbox font, save the old font
CFont* pOldFont = pDC->SelectObject(pFont);
// Get the text metrics for avg char width
pDC->GetTextMetrics(&tm);
for (int i = 0; i < pmyListBox->GetCount(); i++)
{
pmyListBox->GetText(i, str);
sz = pDC->GetTextExtent(str);
// Add the avg width to prevent clipping
sz.cx += tm.tmAveCharWidth;
if (sz.cx > dx)
dx = sz.cx;
}
// Select the old font back into the DC
pDC->SelectObject(pOldFont);
pmyListBox->ReleaseDC(pDC);
// Set the horizontal extent so every character of all strings
// can be scrolled to.
pmyListBox->SetHorizontalExtent(dx);//设置横向滚动条宽度,以像素为单位
}
第四个问题:搜索一个目录下的符合多个通配的文件
主要三点
1 用CString的Tokenize分离多个通配字符串,以";"分隔
2 CFileFind类按通配查找文件
3 显示在ListBox中
void CMyRenamerDlg::DisplayFile(CString &strPath)
{
CFileFind finder;
CString szPath;
if (m_strExt == "")
m_strExt = "*.*";
CString resToken;
int curPos= 0;
resToken= m_strExt.Tokenize(";",curPos);
m_FileList.ResetContent();
while (resToken != "")
{
szPath = strPath + "//"+resToken;
BOOL bWorking = finder.FindFile(szPath);
while (bWorking)
{
bWorking = finder.FindNextFile();
if (!finder.IsDirectory())
{
m_FileList.AddString(finder.GetFileName());
}
}
resToken= m_strExt.Tokenize(";",curPos);
};
ListHScroll();
}
第五个问题:根据选项批量修改文件名
void CMyRenamerDlg::OnBnClickedButtonModify()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
int affirm = AfxMessageBox("即将更改全部选定文件名,你确认要这样做吗?",MB_OKCANCEL);
if (affirm == IDCANCEL)
return;
int nCount = m_FileList.GetSelCount();
CArray<int,int> aryListBoxSel;
CString str;
CString oldStr;
CString oldPath;
CString newPath;
aryListBoxSel.SetSize(nCount);
m_FileList.GetSelItems(nCount, aryListBoxSel.GetData());
for (int i=0;i<aryListBoxSel.GetCount();i++)
{
m_intNum = 1 + i * m_intIncrement;
m_FileList.GetText(aryListBoxSel[i],str);
oldStr = str;
ModifyFileName(str);
if ((str[0] != '.')&&(str != ""))
{
oldPath = m_strCurPath + '//'+oldStr;
newPath = m_strCurPath + '//'+str;
CFile::Rename(oldPath,newPath);
}
}
DisplayFile(m_strCurPath);
UpdateData(FALSE);
}
void CMyRenamerDlg::ModifyFileName(CString & strFileName)
{
UpdateData(TRUE);
int pos = strFileName.ReverseFind('.');
CString title,
extension("");
if (pos == -1)
title = strFileName;
else
{
title = strFileName.Left(pos);
extension = strFileName.Right(strFileName.GetLength()-pos-1);
}
switch (m_radToModify)
{
case 0:
ModifyFileTitle(title);
break;
case 1:
ModifyFileExt(extension);
break;
case 2:
ModifyFileTitle(title);
ModifyFileExt(extension);
break;
}
if (extension != "")
strFileName = title + '.'+extension;
else
strFileName = title;
}
void CMyRenamerDlg::ModifyFileTitle(CString& title)
{
CString strNum;
strNum.Format("%d",m_intNum);
int pos;
switch (m_radPreMode)
{
case 0:
title = m_strNewPre + strNum;
break;
case 1:
if (m_chkNoIncrement)
title = m_strNewPre + title;
else
title = m_strNewPre + strNum + title;
break;
case 2:
if (m_chkNoIncrement)
title = title + m_strNewPre;
else
title = title + m_strNewPre + strNum;
break;
case 3:
pos = title.Find(m_strNewPre);
if (pos != -1)
title.Delete(pos,m_strNewPre.GetLength());
break;
}
}
void CMyRenamerDlg::ModifyFileExt(CString& extension)
{
switch (m_radExtMode)
{
case 0:
extension = m_strNewExt;
break;
case 1:
extension = m_strNewExt + extension;
break;
case 2:
extension = extension + m_strNewExt;
}
}