Click here to Skip to main content
15,895,799 members
Articles / Desktop Programming / MFC

MP3 Rename - a program to rename your MP3s to match their ID3 tags

Rate me:
Please Sign up or sign in to vote.
3.46/5 (10 votes)
10 Nov 2002 102.5K   1.2K   43  
A simple C++ (MFC) program that can rename your MP3 files to match their ID3 tags.
// MP3 RenameDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MP3 Rename.h"
#include "MP3 RenameDlg.h"
#include "DialogHelpMain.h"
#include "DialogAbout.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CMP3RenameDlg dialog



CMP3RenameDlg::CMP3RenameDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMP3RenameDlg::IDD, pParent)
	, m_str_Directory(_T("c:\\"))
	, m_str_mp3list(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMP3RenameDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_ED_DIR, m_str_Directory);
	DDX_Control(pDX, IDC_LST_FILELIST, m_lst_mp3list);
	DDX_LBString(pDX, IDC_LST_FILELIST, m_str_mp3list);
	DDX_Control(pDX, IDOK, m_btn_Rename);
	DDX_Control(pDX, IDC_BTN_OPTIONS, m_btn_options);
	DDX_Control(pDX, IDC_BTN_SELECTALL, m_btn_selectAll);
	DDX_Control(pDX, IDC_BTN_SELECTNONE, m_btn_selectNone);
	DDX_Control(pDX, IDC_BTN_BROWSE, m_btn_browse);
	DDX_Control(pDX, IDC_BTN_STOP, m_btn_stop);
	DDX_Control(pDX, IDC_BTN_HELP, m_btn_help);
}

BEGIN_MESSAGE_MAP(CMP3RenameDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//ON_WM_IDLE()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BTN_OPTIONS, OnBnClickedBtnOptions)
	ON_BN_CLICKED(IDC_BTN_SELECTALL, OnBnClickedBtnSelectall)
	ON_BN_CLICKED(IDOK, OnBnClickedOk)
	ON_BN_CLICKED(IDC_BTN_BROWSE, OnBnClickedBtnBrowse)
	ON_BN_CLICKED(IDC_BTN_SELECTNONE, OnBnClickedBtnSelectnone)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BTN_STOP, OnBnClickedBtnStop)
	ON_BN_CLICKED(IDC_BTN_HELP, OnBnClickedBtnHelp)
END_MESSAGE_MAP()


// CMP3RenameDlg message handlers

BOOL CMP3RenameDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	//set the help button icon (system standard)
	m_btn_help.SetIcon(LoadIcon(NULL, IDI_QUESTION));

	//launch disclaimer (definitely needed)
	MessageBox("Nothing bad should happen, but I am not responsible\nfor any damage to your computer or your mp3s",
				"DISCLAIMER",MB_OK);
	
	m_b_renamingNow = false;
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMP3RenameDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	//I had to manually remove the original about box info becuase
	//	of many problems with HTML Dialogs
	CDialog::OnSysCommand(nID, lParam);
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMP3RenameDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

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

		// Center icon in client rectangle
		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;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMP3RenameDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CMP3RenameDlg::OnBnClickedBtnOptions()
{
	//launch the options dialog
	optionsDlg.DoModal();
}

void CMP3RenameDlg::OnBnClickedBtnSelectall()
{
	//select all in the list
	if(m_lst_mp3list.GetCount() != 0)
		m_lst_mp3list.SelItemRange(TRUE,0,m_lst_mp3list.GetCount() - 1);
}

void CMP3RenameDlg::OnBnClickedBtnSelectnone()
{
	//select none in the list
	if(m_lst_mp3list.GetCount() != 0)
		m_lst_mp3list.SelItemRange(FALSE,0,m_lst_mp3list.GetCount() - 1);
}

void CMP3RenameDlg::OnBnClickedOk()
{
	//make sure that something is selected
	if(m_lst_mp3list.GetSelCount() != 0)
	{
		//set the size of the CArray
		mp3SelList.SetSize(m_lst_mp3list.GetSelCount());
		//add data to the CArray
		m_lst_mp3list.GetSelItems(m_lst_mp3list.GetSelCount(),mp3SelList.GetData());

		//disable windows (so the user can't do anything bad during processing)
		m_btn_Rename.EnableWindow(FALSE);
		m_btn_options.EnableWindow(FALSE);
		m_btn_selectAll.EnableWindow(FALSE);
		m_btn_selectNone.EnableWindow(FALSE);
		m_btn_browse.EnableWindow(FALSE);
		m_btn_stop.EnableWindow(TRUE);

		//set a timer to rn every 10ms
		//	this way, a file will be renamed every 10 ms
		SetTimer(9999,10,NULL);
	}

	//##==-- Don't uncomment, it will make the program quit (and crash) --==##
	//OnOK();
}

void CMP3RenameDlg::OnBnClickedBtnBrowse()
{

	CString	tempString;

	//launch dialog folder
	if(dlgFolder.DoModal() == IDOK)
	{
		//clear mp3 list
		while(m_lst_mp3list.GetCount() != 0)
			m_lst_mp3list.DeleteString(0);

		//create directory string
		m_str_Directory = dlgFolder.GetFolderPath();
		m_str_Directory += '\\';

		//set windows default directory to that
		SetCurrentDirectory(m_str_Directory);

		//search for mp3s in that directory and add them to the list
		if(findMP3s.FindFile("*.mp3"))
		{
			while(findMP3s.FindNextFile())
			{
				m_lst_mp3list.AddString(findMP3s.GetFileTitle());
			}
			//add the last one
			m_lst_mp3list.AddString(findMP3s.GetFileTitle());
		}
	}
	else	//nothing (yet)
	{
	}

	UpdateData(FALSE);	//save new information (update the edit boxes)
}

void CMP3RenameDlg::OnTimer(UINT nIDEvent)
{
	CString		tempString;					//holds the original filename
	CString		artist,album,title,track;	//temporarily holds song info

	CString		renameString;				//to be renamed (at end)
	char		tempTrack[10];				//char array for track (for itoa())
	bool		goodArtist,goodAlbum,goodTitle,goodTrack;

	//used to see if we will ever get a file name that is all 'nothing'
	goodArtist = goodAlbum = goodTitle = goodTrack = true;

	//make sure the event is correct (rename timer event)
	if(nIDEvent == 9999)
	{
		//check to see if another process with this function is running
		if(!m_b_renamingNow)
		{
			m_b_renamingNow = true;	//set flag

			//get original file title
			m_lst_mp3list.GetText(mp3SelList.GetAt(mp3SelList.GetCount()-1),tempString);

			//add extention
			tempString += ".mp3";

			//make sure that we're not stuck in a loop (check the previous
			//	filename against the current one)
			if(m_str_oldName != tempString)
			{
				//save this name
				m_str_oldName = tempString;

				//open the file for reading
				mp3File.Open(tempString);

				//fix rename string
				renameString = "";

				//check to see if the artist info is wanted
				if(optionsDlg.m_b_Artist)
				{
					//get the artist from the file
					artist = mp3File.GetArtist();

					//remove blank spaces from the end
					while(artist.GetLength() != 0 && artist[artist.GetLength() - 1] == ' ')
						artist.Delete(artist.GetLength() - 1);

					//if nothing is there, use default string
					if(artist.GetLength() == 0)
					{
						artist = "{no artist}";
						goodArtist = false;
					}

					//add prefix, artist, and postfix to rename string
					renameString += optionsDlg.m_str_artistPrefix;
					renameString += artist;
					renameString += optionsDlg.m_str_artistSuffix;

					//check if we need a separator
					if(optionsDlg.m_b_Album || optionsDlg.m_b_Track || optionsDlg.m_b_Title)
						renameString += optionsDlg.m_str_separator;
				}
				else
					goodArtist = false;

				//check to see if the album info is wanted
				if(optionsDlg.m_b_Album)
				{
					//get album info from file
					album = mp3File.GetAlbum();

					//remove blank spaces from end
					while(album.GetLength() != 0 && album[album.GetLength() - 1] == ' ')
						album.Delete(album.GetLength() - 1);

					//if nothing is there, use default string
					if(album.GetLength() == 0)
					{
						album = "{no album}";
						goodAlbum = false;
					}

					//add prefix, album, suffix
					renameString += optionsDlg.m_str_albumPrefix;
					renameString += album;
					renameString += optionsDlg.m_str_albumSuffix;

					//check if we need a separator
					if(optionsDlg.m_b_Track || optionsDlg.m_b_Title)
						renameString += optionsDlg.m_str_separator;
				}
				else
					goodAlbum = false;

				//check to see if the track info is wanted
				if(optionsDlg.m_b_Track)
				{
					//get track info from file and convert to char[]
					itoa(mp3File.GetTrack(),tempTrack,10);
					//save char[] at CString
					track = tempTrack;

					//check if track is invalid, rename if it is
					if(track == '0')
					{
						track = "{no track}";
						goodTrack = false;
					}

					//add prefix, track and suffix to rename string
					renameString += optionsDlg.m_str_trackPrefix;
					renameString += track;
					renameString += optionsDlg.m_str_trackSuffix;

					//check if we need a separator
					if(optionsDlg.m_b_Title)
						renameString += optionsDlg.m_str_separator;
				}
				else
					goodTrack = false;

				//check to see if the title info is wanted
				if(optionsDlg.m_b_Title)
				{
					//get title from file
					title = mp3File.GetTitle();
					//remove blank spaces
					while(title.GetLength() != 0 && title[title.GetLength() - 1] == ' ')
						title.Delete(title.GetLength() - 1);

					//if empty, replace with default string
					if(title.GetLength() == 0)
					{
						title = "{no title}";
						goodTitle = false;
					}

					//add prefix, title, and suffix to rename string
					renameString += optionsDlg.m_str_titlePrefix;
					renameString += title;
					renameString += optionsDlg.m_str_titleSuffix;

				}
				else
					goodTitle = false;

				//replace any invalid characters in rename string
				StringReplace(renameString);

				//if what we want to call the string already exists, add 'copy' to the
				//	end of this one
				while(findMP3s.FindFile(renameString + ".mp3"))
					renameString += " copy";

				//add extention to rename string
				renameString += ".mp3";

				//DO THE RENAME!!! (make sure something will be there first
				if(goodArtist || goodAlbum || goodTrack || goodTitle)
					CFile::Rename(tempString,renameString);
			}

			//remove the name from the CListBox
			m_lst_mp3list.DeleteString(mp3SelList.GetAt(mp3SelList.GetCount() - 1));
			//remove the name from the CArray
			mp3SelList.RemoveAt(mp3SelList.GetCount() - 1);

			//are we at the end of the list?
			if(mp3SelList.GetCount() == 0)
			{
				//if yes, stop the timer and re-enable the buttons
				KillTimer(9999);
				m_btn_stop.EnableWindow(FALSE);
				m_btn_Rename.EnableWindow(TRUE);
				m_btn_options.EnableWindow(TRUE);
				m_btn_selectAll.EnableWindow(TRUE);
				m_btn_selectNone.EnableWindow(TRUE);
				m_btn_browse.EnableWindow(TRUE);
			}

			//set flag so something else can work
			m_b_renamingNow = false;
		}
	}

	CDialog::OnTimer(nIDEvent);
}

void CMP3RenameDlg::OnBnClickedBtnStop()
{
	//stop the timer and enable the buttons
	KillTimer(9999);
	m_btn_stop.EnableWindow(FALSE);
	m_btn_Rename.EnableWindow(TRUE);
	m_btn_options.EnableWindow(TRUE);
	m_btn_selectAll.EnableWindow(TRUE);
	m_btn_selectNone.EnableWindow(TRUE);
	m_btn_browse.EnableWindow(TRUE);
}

void CMP3RenameDlg::StringReplace(CString& string)
{
	//replace invalid filename characters
	string.Replace('\\','_');
	string.Replace('/','_');
	string.Replace(':','_');
	string.Replace('*','_');
	string.Replace('?','_');
	string.Replace('\"','_');
	string.Replace('<','_');
	string.Replace('>','_');
	string.Replace('|','_');
	string.Replace('\n','_');
	string.Replace('\t','_');
}

void CMP3RenameDlg::OnBnClickedBtnHelp()
{
	//launch help dialog
	DialogHelpMain	helpdlg;

	helpdlg.DoModal();
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
it's me... Jonathan D.
from upstate NY....uh....
like my stuff? let me know!

Comments and Discussions