⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp3listbox.cpp

📁 一些关于C++开发的多媒体制作书籍的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
* Copyright (c) 2002, Bcdliang
* All rights reserved.
*
* 文件名称:MP3ListBox.h
* 摘    要:类CMP3ListBox的实现
*
* 当前版本:1.01
* 作    者:LIANG Zheng
* 完成日期:2002年8月11日
*/

#include "stdafx.h"
#include "SimpleMP3.h"
#include "MP3ListBox.h"
#include "ID3TAGDlg.h"
#include <strstrea.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMP3ListBox

CMP3ListBox::CMP3ListBox()
{
	this->m_iHotItemID = -1;
	this->m_rTitle=CRect(0, 0, 0, 0);
	this->m_rLength=CRect(0, 0, 0, 0);
	this->m_crNormalBk = ::GetSysColor(COLOR_WINDOW);
	this->m_crNormalText = ::GetSysColor(COLOR_WINDOWTEXT);
	this->m_crSelectedBk = ::GetSysColor(COLOR_HIGHLIGHT);
	this->m_crSelectedText = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
	this->m_crHotBk = ::GetSysColor(COLOR_WINDOW);
	this->m_crHotText = RGB(0, 0, 255);	//::GetSysColor(COLOR_HOTLIGHT);
	this->m_hBrush = (HBRUSH)::CreateSolidBrush(this->m_crNormalBk);

	m_bMouseDown = false;
	m_bDragging = false;
	m_nCurrentItem = 0;
	m_nSelCount = 0;
	m_pSelItems = NULL;
	m_pSelValues = NULL;

	m_hAccTable = ::LoadAccelerators(AfxGetInstanceHandle(),
		MAKEINTRESOURCE(IDR_LISTBOXACCELERATOR));
}

CMP3ListBox::~CMP3ListBox()
{
	::DeleteObject(m_hBrush);
}


BEGIN_MESSAGE_MAP(CMP3ListBox, CListBox)
	ON_WM_CONTEXTMENU()
	//{{AFX_MSG_MAP(CMP3ListBox)
	ON_WM_CTLCOLOR_REFLECT()
	ON_COMMAND(ID_LISTMENU_DELETE, OnListmenuDelete)
	ON_COMMAND(ID_LISTMENU_INFO, OnListmenuInfo)
	ON_COMMAND(ID_LISTMENU_PLAY, OnListmenuPlay)
	ON_CONTROL_REFLECT(LBN_DBLCLK, OnDblclk)
	ON_WM_DESTROY()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_SETCURSOR()
	ON_COMMAND(IDA_DELETE, OnListmenuDelete)
	ON_COMMAND(IDA_INFO, OnListmenuInfo)
	ON_COMMAND(IDA_LISTPLAY, OnListmenuPlay)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMP3ListBox message handlers

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:DrawItem
* 函数介绍:重写父类函数DrawItem, 画出有着自定义文字颜色和底色的列表项
* 输入参数:LPDRAWITEMSTRUCT lpDrawItemStruct
* 输出参数:无
* 返回值  :无
*/
void CMP3ListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	CString sText=_T("");                       // No Need To Reallocate Each Time

	CDC dcContext;
	int iItem = lpDrawItemStruct -> itemID;
//	int iAction = lpDrawItemStruct -> itemAction;
	int iState = lpDrawItemStruct -> itemState;
	CRect rItemRect( lpDrawItemStruct -> rcItem );
	CRect rBlockRect( rItemRect );
	this->m_rTitle=rItemRect;
	this->m_rTitle.right = rItemRect.right - CMP3ListBox::MLB_LENGTH_WIDTH;
	this->m_rLength=rItemRect;
	this->m_rLength.left = rItemRect.left - CMP3ListBox::MLB_TITLE_WIDTH;

	if( !dcContext.Attach( lpDrawItemStruct -> hDC ) )  // Attach CDC Object
		return;                                   // Stop If Attach Failed

	COLORREF crTextColor = this->m_crNormalText;
	COLORREF crBkColor = this->m_crNormalBk;
	if (this->m_iHotItemID == iItem)
		crTextColor = this->m_crHotText;

	if( iState & ODS_SELECTED )                        // If Selected
	{                                         // Set Selected Attributes
		//crTextColor = this->m_crNormalText;           // Selected text's color is similiar to the current text color
		crBkColor = this->m_crSelectedBk;             // Set BG To Highlight Color
	}

	dcContext.SetBkMode( OPAQUE );             // Transparent Background

	dcContext.SetTextColor(crTextColor);
	dcContext.SetBkColor(crBkColor);             // Set BG To Highlight Color
	dcContext.FillSolidRect( &rBlockRect, crBkColor);   // Erase Item

//	if( iState & ODS_FOCUS )                       // If Item Has The Focus
//		dcContext.DrawFocusRect( &rItemRect );      // Draw Focus Rect

   //
   // Calculate Text Area
   //
	this->m_rTitle.DeflateRect(4,0);
	this->m_rLength.DeflateRect(4,0);

	//
	// Draw Color Text And Block
	//
	if( iItem != -1 )                            // If Not An Empty Item
	{
		sText = this->GetTitle(iItem);
		DrawText(dcContext.GetSafeHdc(),
			sText, 
			strlen(sText), 
			this->m_rTitle, 
			DT_WORD_ELLIPSIS | DT_LEFT | DT_SINGLELINE | DT_VCENTER);		// this won't modify the string!
//		TRACE(sText);
		sText = this->GetLength(iItem);
		DrawText(dcContext.GetSafeHdc(),
			sText, 
			strlen(sText), 
			this->m_rLength, 
			DT_WORD_ELLIPSIS | DT_RIGHT | DT_SINGLELINE | DT_VCENTER);		// this won't modify the string!
	}
	dcContext.Detach();	

}

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:AddFile
* 函数介绍:按指定的Path往LISTBOX中加入一个MP3文件:
                用new申请一个新项(CMP3ListBoxItem), 并以{strPath, "", ""}填充, 
			然后往LISTBOX加入一个条目(其值为指向该项的指针),并更新该新项
* 输入参数:const CString &strPath, 要加入的条目
* 输出参数:无
* 返回值  :int, 父类成员AddString的返回值, LB_ERR或LB_ERRSPACE为出错
*/
int CMP3ListBox::AddFile(const CString &strPath)
{
	int ret;

	m_pItem = new CMP3ListBoxItem;
	m_pItem->m_Path = strPath;
	m_pItem->m_Title = _T("");
	m_pItem->m_Length = _T("");

	ret = CListBox::AddString((LPCTSTR)m_pItem);
	if (ret == LB_ERR || ret == LB_ERRSPACE)
		return ret;

	this->UpdateSongInfo(this->GetCount()-1);

	return ret;
}

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:DeleteFile
* 函数介绍:删除对应项的数据(CMP3ListBoxItem), 然后删除该项
* 输入参数:UINT nIndex, 要删除的条目的Index
* 输出参数:无
* 返回值  :int, 父类成员DeleteString的返回值, LB_ERR为出错
*/
int CMP3ListBox::DeleteFile(UINT nIndex)
{
	m_pItem = (CMP3ListBoxItem *)GetItemData(nIndex);
	delete m_pItem;

	return CListBox::DeleteString(nIndex);
}

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:DeleteSelectedFiles
* 函数介绍:删除所有选定项的数据(CMP3ListBoxItem), 然后删除所有选定项
* 输入参数:无
* 输出参数:无
* 返回值  :int, 删除项的数目
*/
int CMP3ListBox::DeleteSelectedFiles()
{
	int iSelCount = GetSelCount();
	int i;

	if (iSelCount < 1)
		return 0;

	//取得选中的各项...
	LPINT rgIndex;

	rgIndex = new int[iSelCount];
	GetSelItems(iSelCount, rgIndex);
	
	//删除各项(从后往前删)...
	for (i=iSelCount-1; i>=0; i--)
	{
		m_pItem = (CMP3ListBoxItem *)GetItemData(*(rgIndex+i));
		delete m_pItem;
		CListBox::DeleteString(*(rgIndex+i));
	}
	delete rgIndex;

	return iSelCount;
}

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:DeleteAllFiles
* 函数介绍:删除所有项的数据(CMP3ListBoxItem), 然后删除所有项
* 输入参数:无
* 输出参数:无
* 返回值  :无
*/
void CMP3ListBox::DeleteAllFiles()
{
	for (int i=0; i<GetCount(); i++)
	{
		m_pItem = (CMP3ListBoxItem *)GetItemData(i);
		delete m_pItem;
	}

	CListBox::ResetContent();
}

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:AddDir
* 函数介绍:向列表中加入某一目录(包括子目录)中的所有MP3文件, 递归调用自身
* 输入参数:LPVOID lpvoid, 目录的全路径
* 输出参数:无
* 返回值  :无
*/
void CMP3ListBox::AddDir(LPVOID lpvoid)
{
	CFileFind f;
	CString strFilePath=_T(""), strFileExt=_T("");
	LPSTR lpstr=(LPSTR) lpvoid;
	BOOL b;

	SetCurrentDirectory(lpstr);
//	_chdir(lpstr);
	b=f.FindFile("*.*");
	while (b)
	{	b=f.FindNextFile();
		strFilePath=f.GetFilePath();
		if (f.IsDirectory())
		{	if (!f.IsDots())
				AddDir(strFilePath.GetBuffer(255));
		}else
		{	strFileExt=strFilePath.Right(3);
			strFileExt.MakeUpper();
			if (strFileExt=="MP3")
			{
				AddFile(strFilePath);
			}
		}
	}
	// handle all the message in the message loop
	MSG msg;
	while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE) )
		DispatchMessage(&msg);
}

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:SetTitle
* 函数介绍:设置Title字符串
* 输入参数:UINT uItemID, 要设置的条目
            CString strNewTitle, 新Title字符串, 格式为:
                 作者 - 歌名
* 输出参数:无
* 返回值  :无
*/
void CMP3ListBox::SetTitle(UINT uItemID, const CString &strNewTitle)
{
	m_pItem = (CMP3ListBoxItem *)GetItemData(uItemID);
	m_pItem->m_Title = strNewTitle;
}

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:GetTitle
* 函数介绍:查询Title字符串
* 输入参数:UINT uItemID, 要查询的条目
* 输出参数:无
* 返回值  :CString, Title字符串, 格式为:
            3.作者 - 歌名
*/
CString CMP3ListBox::GetTitle(UINT uItemID) const
{
	CString strTitle;
	strTitle.Format("%d.%s", uItemID+1, ((CMP3ListBoxItem *)GetItemData(uItemID))->m_Title);
	return strTitle;
}

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:GetRawTitle
* 函数介绍:查询没有NO的Title字符串
* 输入参数:UINT uItemID, 要查询的条目
* 输出参数:无
* 返回值  :CString, 没有NO的Title字符串, 格式为:
            作者 - 歌名
*/
CString CMP3ListBox::GetRawTitle(UINT uItemID) const
{
	return ((CMP3ListBoxItem *)GetItemData(uItemID))->m_Title;
}


////////////////////////////////////////////////////////////////////////
/*
* 函数名称:SetLength
* 函数介绍:设置Length字符串
* 输入参数:UINT uItemID, 要设置的条目
            const CString &strNewLength, 新Length字符串, 格式为:
                   00:00
* 输出参数:无
* 返回值  :无
*/
void CMP3ListBox::SetLength(UINT uItemID, const CString &strNewLength)
{
	((CMP3ListBoxItem *)GetItemData(uItemID))->m_Length = strNewLength;
}

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:GetLength
* 函数介绍:查询Length字符串
* 输入参数:UINT uItemID, 要查询的条目
* 输出参数:无
* 返回值  :CString, Length字符串, 格式为:
            00:00
*/
CString CMP3ListBox::GetLength(UINT uItemID) const
{
	return ((CMP3ListBoxItem *)GetItemData(uItemID))->m_Length;
}

////////////////////////////////////////////////////////////////////////
/*
* 函数名称:GetRawLength
* 函数介绍:将Length字符串转换为秒数字符串并返回
* 输入参数:UINT uItemID, 要查询的条目
* 输出参数:无
* 返回值  :CString, 对应于Length字符串的秒数字符串
*/
CString CMP3ListBox::GetRawLength(UINT uItemID) const
{
	CString sLength = ((CMP3ListBoxItem *)GetItemData(uItemID))->m_Length;
	int iMin, iSec;

	sLength.SetAt(sLength.Find(':'), '\t');
	istrstream buffer(sLength.GetBuffer(1));
	sLength.ReleaseBuffer();
	buffer>>iMin>>iSec;
	sLength.Format("%d", iMin*60+iSec);
	return sLength;
}

////////////////////////////////////////////////////////////////////////
/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -