📄 mp3listbox.cpp
字号:
/*
* 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 + -