批量重命名工具 MFC版 VS2010编写

最近在做一个项目,需要对一批文件进行批量重命名操作,百度了一下,下载到的几个工具感觉不太容易使用。

于是自己用VS2010做了一个。

界面如下图:

批量重命名工具 MFC版 VS2010编写_第1张图片

下载地址:  (源代码+详细注释版)

 

部分关键代码:

 

// LBatchRenameDlg.h : 头文件
//

#pragma once
#include "PictureButton.h"
#include "afxwin.h"
#include <vector>
using namespace std;
#pragma warning(disable:4705)


// CLBatchRenameDlg 对话框
class CLBatchRenameDlg : public CDialogEx
{
// 构造
public:
	CLBatchRenameDlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum { IDD = IDD_LBATCHRENAME_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()

public:
	afx_msg void OnBnClickedSelectFolder();
	afx_msg void OnBnClickedConfirmTransfer();

private:
	CPictureButton m_btnAdvancedSetting;// 本来是想做个“高级功能”按钮,最后还是换成了一个超链接
	CPictureButton m_btnSelectFolder;	// 选择文件的按钮(继承的CButtonST类,方便操作)
	CComboBox m_comboNum;	// combo控件选择框的控制变量
	CString m_sFormat;		// 文件名格式
	CString folderPath;		// 用户选择的文件夹
	CListBox m_listOldFile;	// ListBox控件,左下角的原文件名
	CListBox m_listNewFile;	// 右下角的新文件名
	vector<int> iFailedVec;	// 重命名失败的文件编号

public:
	void ScanFolder(void);
	afx_msg void OnCbnSelchangeCombo1();
	void UpdateFormat(void);
	afx_msg void OnEnChangeFormat();
	void UpdateNewFileNameList(void);
	afx_msg void OnBnClickedAdvancedSetting();
};

 下面是Dlg的cpp文件内容:

// LBatchRenameDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "LBatchRename.h"
#include "LBatchRenameDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CLBatchRenameDlg 对话框




CLBatchRenameDlg::CLBatchRenameDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CLBatchRenameDlg::IDD, pParent)
	, m_sFormat(_T("【散人终曲】*【】"))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CLBatchRenameDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, ID_SELECT_FOLDER, m_btnSelectFolder);
	DDX_Control(pDX, IDC_COMBO1, m_comboNum);
	DDX_Text(pDX, IDC_FORMAT, m_sFormat);
	DDX_Control(pDX, IDC_OLDFILE, m_listOldFile);
	DDX_Control(pDX, IDC_NEWFILE, m_listNewFile);
	DDX_Control(pDX, IDC_ADVANCED_SETTING, m_btnAdvancedSetting);
}

BEGIN_MESSAGE_MAP(CLBatchRenameDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(ID_SELECT_FOLDER, &CLBatchRenameDlg::OnBnClickedSelectFolder)
	ON_BN_CLICKED(IDC_CONFIRM_TRANSFER, &CLBatchRenameDlg::OnBnClickedConfirmTransfer)
	ON_CBN_SELCHANGE(IDC_COMBO1, &CLBatchRenameDlg::OnCbnSelchangeCombo1)
	ON_EN_CHANGE(IDC_FORMAT, &CLBatchRenameDlg::OnEnChangeFormat)
END_MESSAGE_MAP()


// CLBatchRenameDlg 消息处理程序

BOOL CLBatchRenameDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	m_btnSelectFolder.SetBitmapImage(IDB_FOLDER);
	m_comboNum.SetCurSel(3);
	m_btnAdvancedSetting.SetBitmapImage(IDB_LINKME);
	m_btnAdvancedSetting.SetURL(_T("http://blog.csdn.net/luofl1992"));	// 超链接,点击后进入

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CLBatchRenameDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CLBatchRenameDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CLBatchRenameDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CLBatchRenameDlg::OnBnClickedSelectFolder()
{
	// TODO: 在此添加控件通知处理程序代码
	BROWSEINFO browseInfo;  
	::ZeroMemory(&browseInfo, sizeof(BROWSEINFO));//CString strPath = _T("");   
	TCHAR szBuffer[MAX_PATH]  = {0};  
	browseInfo.hwndOwner      = NULL;  
	browseInfo.pszDisplayName = szBuffer;  
	browseInfo.ulFlags        = BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS;  
	LPITEMIDLIST pIDList      = SHBrowseForFolder(&browseInfo);  
	if(pIDList == NULL)  
		return;  
	SHGetPathFromIDList(pIDList, szBuffer);  
	LPMALLOC lpMalloc;  
	if(FAILED(SHGetMalloc(&lpMalloc)))   
		return;  
	lpMalloc->Free(pIDList);  
	lpMalloc->Release();
	folderPath.Format(_T("%s"), szBuffer); 
	SetDlgItemText( IDC_FOLDER, folderPath);
	UpdateFormat();		// 更新输出格式
	SetDlgItemText( IDC_STATE, _T("正在扫描文件") );
	ScanFolder();
	SetDlgItemText( IDC_STATE, _T("扫描文件完成") );
}


void CLBatchRenameDlg::OnBnClickedConfirmTransfer()
{
	// TODO: 在此添加控件通知处理程序代码
	CString sState(_T("正在转化中"));
	CString fileName;
	CString oldFileName;
	CString newFileName;
	SetDlgItemText( IDC_STATE, sState );
	folderPath.Append(_T("\\"));
	for ( int i = 0; i < m_listOldFile.GetCount(); i++ )
	{
		m_listOldFile.GetText( i, fileName );
		oldFileName = folderPath + fileName;
		m_listNewFile.GetText( i, fileName);
		newFileName = folderPath + fileName;
		// 此处进行重命名处理
		try
		{
			CFile::Rename( oldFileName, newFileName);
		}
		catch (CFileException* e)
		{
			iFailedVec.push_back(i);		// 记录编号未完成
		}
		if ( i % 10 == 0 )
		{
			sState.Format(_T("重命名已完成%.2f%%"), 100.0f * i / m_listOldFile.GetCount());
			SetDlgItemText( IDC_STATE, sState );
		}
	}
	SetDlgItemText( IDC_STATE, _T("全部工作完成!") );
	fileName.Format(_T("全部文件共计%d个,失败%d个"), m_listOldFile.GetCount(), iFailedVec.size() );
	MessageBox(fileName, _T("操作完成"));
}


void CLBatchRenameDlg::ScanFolder(void)
{
	// 扫描源文件夹下的所有文件
	CString sState;
	int istate = 0;
	CString szFind(folderPath);
	WIN32_FIND_DATA FindFileData;
	int findFileCount = 0;
	szFind.Append(_T("\\*.*"));
	HANDLE hFind = FindFirstFile(szFind, &FindFileData);
	if(INVALID_HANDLE_VALUE == hFind) return;
	while( 1 )
	{
		if( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
		{
			// 对于文件夹不做任何操作
			// 如果是对文件夹重命名,则在此进行操作
		}
		else
		{
			// 普通文件
			m_listOldFile.AddString( FindFileData.cFileName );
			szFind.Format( m_sFormat, ++findFileCount );	// 编号从1开始
			m_listNewFile.AddString(szFind);
		}
		if(!FindNextFile( hFind, &FindFileData))
			break;		// 遍历文件夹完毕,则终止循环
		sState.Format(_T("正在扫描文件."));
		for ( int i = 0; i < istate; i++ )
			sState.Append(_T("."));
		SetDlgItemText( IDC_STATE, sState );
		istate = (istate + 1) % 6 ;
	}
	FindClose(hFind);
}


void CLBatchRenameDlg::OnCbnSelchangeCombo1()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateNewFileNameList();		// 更新新的文件名ListBox的数值
}


void CLBatchRenameDlg::OnEnChangeFormat()
{
	// TODO:  如果该控件是 RICHEDIT 控件,它将不
	// 发送此通知,除非重写 CDialogEx::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask(),
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

	// TODO:  在此添加控件通知处理程序代码
	UpdateNewFileNameList();		// 更新新的文件名ListBox的数值
}


void CLBatchRenameDlg::UpdateFormat(void)
{
	// 更新新文件名的格式
	UpdateData(TRUE);		// 刷新外部控件的数值到内部变量
	CString sNum;
	sNum.Format(_T("%%0%dd"), m_comboNum.GetCurSel());
	m_sFormat.Replace( _T("*"), sNum );
}


void CLBatchRenameDlg::UpdateNewFileNameList(void)
{
	//	更新新的文件名ListBox的数值
	CString str;
	UpdateFormat();					// 更新新文件名的格式
	m_listNewFile.ResetContent();	// 清空原有内容
	SetDlgItemText( IDC_STATE, m_sFormat );
	for ( int i = 0; i < m_listOldFile.GetCount(); )
	{
		str.Format( m_sFormat, ++i );	// 编号从1开始,而不是0
		m_listNewFile.AddString(str);
	}
}


 

 

你可能感兴趣的:(批量重命名工具 MFC版 VS2010编写)