利用c++以及一些函数库制作一个简单的音乐播放器。
成果:
实现了:打开一个音频文件,播放音频,中途暂停或继续,停止换歌,滑动控制音量大小。
本人也是根据视频教程所学,内容相同。可点击链接去观看免费教学视频。
对于代码的讲解,建议观看视频,本人不再赘述,主要讲述一些本人在实现过程中遇到的问题。
这是因为你可能在没有更改对应的BUTTON ID的时候就双击初始化过一次。需要更改以下内容:
我也在网上搜索了很多答案,发现问题比较一致,在不同平台上下载下来的同一首歌曲的mp3文件,可能包含的内容不相同。可能会包含封面或者其他内容,例如该专辑的分面。
解决方法:换个平台下载歌曲,毕竟现在的重点不是怎么去改mp3文件。
如果找不到合适的mp3文件。可以下载本人找到的一个可以使用的歌曲的文件(啥歌名,别问我,我也忘了):
百度网盘链接:https://pan.baidu.com/s/1WWUWaUnnf97ABRa7au9RRw
提取码:4m5b
// MusicPlayerDlg.cpp: 实现文件
//
#include "stdafx.h"
#include "MusicPlayer.h"
#include "MusicPlayerDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMusicPlayerDlg 对话框
CMusicPlayerDlg::CMusicPlayerDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_MUSICPLAYER_DIALOG, pParent)
, m_nvolume(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_DeviceID = 0;
}
void CMusicPlayerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_SLIDER1, m_slider);
DDX_Text(pDX, IDC_EDIT1, m_nvolume);
}
BEGIN_MESSAGE_MAP(CMusicPlayerDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_OPEN, &CMusicPlayerDlg::OnBnClickedBtnOpen)
ON_BN_CLICKED(IDC_BTN_PLAY, &CMusicPlayerDlg::OnBnClickedBtnPlay)
ON_BN_CLICKED(IDC_BTN_PAUSE, &CMusicPlayerDlg::OnBnClickedBtnPause)
ON_BN_CLICKED(IDC_BTN_STOP, &CMusicPlayerDlg::OnBnClickedBtnStop)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER1, &CMusicPlayerDlg::OnCustomdrawSlider1)
END_MESSAGE_MAP()
// CMusicPlayerDlg 消息处理程序
BOOL CMusicPlayerDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
//设置范围
m_slider.SetRange(0, 100);
m_slider.SetPos(50);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CMusicPlayerDlg::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
{
CPaintDC dc(this);
//获取客户区大小
CRect rect;
GetClientRect(&rect);
//dc.FillSolidRect(&rect, RGB(192,192,0));
//改变字体
CFont font;
font.CreatePointFont(120, L"黑体");
//加载图片
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);
//获取图片的高宽
BITMAP logMap;
bmp.GetBitmap(&logMap);
//创建内存DC
CDC memDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject(&bmp);
//直接贴图
dc.BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);
//拉伸贴图
dc.SetStretchBltMode(HALFTONE);
dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, logMap.bmWidth,logMap.bmHeight,SRCCOPY);
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMusicPlayerDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
//打开
void CMusicPlayerDlg::OnBnClickedBtnOpen()
{
// TODO: 在此添加控件通知处理程序代码
//MessageBox(L"点击了",L"提示",MB_OK);
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,L"MP3文件(*.mp3)|*.mp3|WMA文件(*.wma)|*.wma|WAV文件(*.wav)|*.wav|所有文件(*.*)|*.*||");
if (IDCANCEL == dlg.DoModal())
return;
//获取路径
CString strMusicFile = dlg.GetPathName();
//MessageBox(strMusicFile);
//打开
MCI_OPEN_PARMS mciOpenParms;
mciOpenParms.lpstrElementName = strMusicFile;
MCIERROR mcierror= mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_ELEMENT|MCI_WAIT,(DWORD)&mciOpenParms);
if (mcierror)
{
wchar_t szErrorMsg[256];
//获取错误信息
mciGetErrorString(mcierror,szErrorMsg,256);
MessageBox(szErrorMsg, L"自制播放器");
return;
}
m_DeviceID = mciOpenParms.wDeviceID;
//调用函数自动播放
OnBnClickedBtnPlay();
}
//播放
void CMusicPlayerDlg::OnBnClickedBtnPlay()
{
//初始音量为50
MCI_DGV_SETAUDIO_PARMS mcisetvolume;
mcisetvolume.dwItem = MCI_DGV_SETAUDIO_VOLUME;
mcisetvolume.dwValue = 50;
mciSendCommand(m_DeviceID, MCI_SETAUDIO, MCI_DGV_SETAUDIO_VALUE | MCI_DGV_SETAUDIO_ITEM, (DWORD)&mcisetvolume);
//播放
MCI_PLAY_PARMS mciPlayParms;
mciPlayParms.dwCallback = NULL;
mciPlayParms.dwFrom = 0;
mciSendCommand(m_DeviceID, MCI_PLAY, MCI_FROM | MCI_NOTIFY, (DWORD)&mciPlayParms);
}
//暂停
void CMusicPlayerDlg::OnBnClickedBtnPause()
{
CString str;
GetDlgItemText(IDC_BTN_PAUSE, str);
if (str == L"暂停")
{
mciSendCommand(m_DeviceID,MCI_PAUSE,0,0);
SetDlgItemText(IDC_BTN_PAUSE, L"继续");
}
else if (str == L"继续")
{
mciSendCommand(m_DeviceID, MCI_RESUME, 0, 0);
SetDlgItemText(IDC_BTN_PAUSE, L"暂停");
}
}
//停止
void CMusicPlayerDlg::OnBnClickedBtnStop()
{
mciSendCommand(m_DeviceID, MCI_STOP, 0, 0);
mciSendCommand(m_DeviceID, MCI_CLOSE, 0, 0);
}
//音量控制
void CMusicPlayerDlg::OnCustomdrawSlider1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
//获取当前滑动控件的位置
m_nvolume = m_slider.GetPos();
//更新音量文本框数值显示
UpdateData(FALSE);
//发送命令
MCI_DGV_SETAUDIO_PARMS mcisetvolume;
mcisetvolume.dwItem = MCI_DGV_SETAUDIO_VOLUME;
mcisetvolume.dwValue = m_nvolume;
mciSendCommand(m_DeviceID,MCI_SETAUDIO,MCI_DGV_SETAUDIO_VALUE|MCI_DGV_SETAUDIO_ITEM,(DWORD)&mcisetvolume);
*pResult = 0;
}