I've been busy working on projects recently, and I haven't posted an article for a long time. Okay, let's not talk nonsense
1. Project display
The functions of this music player are clear at a glance, and functions can also be added. Interested masters study and study
2. Key technologies
The whole program mainly realizes the following functions:
1) Volume and playback progress control
2) Top window
3) Basic playback and pause functions
1. Play pause
First, open a file selection dialog box, then get the path of the music file, and play it with the help of the mciSendCommand() function
First look at the MCI_PLAY_PARMS structure on MSDN for playing music
typedef struct {
DWORD_PTR dwCallback;
DWORD dwFrom;
DWORD dwTo;
} MCI_PLAY_PARMS;
dwCallback: The low-order word specifies the window handle for the MCI_NOTIFY flag.
dwFrom: The position to play from.
dwTo: The position to play.
Several MCI commands
MCI_PAUSE Pause
MCI_RESUME Continue playing
MCI_PLAY Play
MCI_OPEN Open
MCI_STATUS Get current duration
MCI_STOP Stop
MCI_CLOSE Close
These commands need to use the mciSendCommand () function
mciSendCommand function to send a command message to the specified MCI device.
MCIERROR mciSendCommand(
MCIDEVICEID IDDevice,
UINT uMsg,
DWORD_PTR fdwCommand,
DWORD_PTR dwParam
);
IDDevice : The device identifier of the MCI device to receive the command message. This parameter is not used with the MCI_OPEN command message.
uMsg : Command message. For a list, see Multimedia Commands.
fdwCommand: Flags for command messages.
dwParam : Pointer to a structure containing command message parameters.
upper code
//打开
void CMusicPlayerDlg::OnBnClickedBtnChoose()
{
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();
SetDlgItemText(IDC_EDIT_NAME, 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;
}
StopMusic();//清除 循环播放
m_DeviceID = mciOpenParms.wDeviceID;
//调用函数自动播放
OnBnClickedBtnPlay();
}
//播放
void CMusicPlayerDlg::OnBnClickedBtnPlay()
{
MCI_PLAY_PARMS mciPlayParms;
mciPlayParms.dwCallback = NULL;
mciPlayParms.dwFrom = 0;
mciSendCommand(m_DeviceID, MCI_PLAY, MCI_FROM | MCI_NOTIFY, (DWORD)&mciPlayParms);
GetDlgItem(IDC_BTN_PAUSE)->EnableWindow(TRUE);
GetDlgItem(IDC_SLIDER_MUSIC)->EnableWindow(TRUE);
GetDlgItem(IDC_SLIDER_VOLUME)->EnableWindow(TRUE);
//获取总长度
CString strLength;
MCI_STATUS_PARMS mciStatusParms;
mciStatusParms.dwItem = MCI_STATUS_LENGTH;
mciSendCommand(m_DeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, (DWORD)&mciStatusParms);
int m_dLength = mciStatusParms.dwReturn;
int minute = 0;//分
int second = m_dLength / 1000;//秒
if (second >= 60)
{
minute = second / 60;
second = second - (60 * minute);
strLength.Format(L"%d:%d", minute, second);
}
m_Silder.SetRange(0, m_dLength);
SetDlgItemText(IDC_EDIT_END, strLength);
SetTimer(1, 200, NULL);//计时器
}
//暂停
void CMusicPlayerDlg::OnBnClickedBtnCause()
{
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"暂停");
}
}
It is divided into three functions here, which are convenient to call later, and a timer is also set, mainly for the playback duration function later
2. Window top
Not much to say, the code
//置顶
void CMusicPlayerDlg::OnBnTopWin()
{
//CButton* pBtn = (CButton*)GetDlgItem(IDC_CHECK1);
//int state = pBtn->GetCheck();
int state= m_TopWin.GetCheck();
if (state == 1)
{
::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
}
else
{
::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
}
3. Volume playback progress
Simple MFC operation
//计时器
void CMusicPlayerDlg::OnTimer(UINT_PTR nIDEvent)
{
switch (nIDEvent)
{
case 1:
CString str;
MCI_STATUS_PARMS mciStatusParms;
mciStatusParms.dwItem = MCI_STATUS_POSITION;
mciSendCommand(m_DeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, (DWORD)&mciStatusParms);
int m_dPosition = mciStatusParms.dwReturn;
int minute = 0;//分
int second = m_dPosition / 1000;//秒
str.Format(L"%d:%d", minute, second);
if (second >= 60)
{
minute = second / 60;
second = second - (60 * minute);
str.Format(L"%d:%d", minute, second);
}
m_Silder.SetPos(m_dPosition);
SetDlgItemText(IDC_EDIT_START, str);
break;
}
CDialogEx::OnTimer(nIDEvent);
}
//进度条
void CMusicPlayerDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
int nId = pScrollBar->GetDlgCtrlID();
int nPostion;
int nVolume;
if (nId == IDC_SLIDER_MUSIC)
{
nPostion = m_Silder.GetPos();
MCI_PLAY_PARMS mciPlayParms;
mciPlayParms.dwFrom = nPostion;
mciSendCommand(m_DeviceID, MCI_PLAY, MCI_FROM, (DWORD)&mciPlayParms);
}
else if (nId == IDC_SLIDER_VOLUME)
{
nVolume = m_Volume.GetPos();
MCI_DGV_SETAUDIO_PARMS mciSetVolume;
mciSetVolume.dwItem = MCI_DGV_SETAUDIO_VOLUME;
mciSetVolume.dwValue = nVolume;
mciSendCommand(m_DeviceID, MCI_SETAUDIO, MCI_DGV_SETAUDIO_VALUE | MCI_DGV_SETAUDIO_ITEM, (DWORD)&mciSetVolume);
}
CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}
Well, share a complete project link
https://fow.lanzouw.com/iHmEE07oga9c
Password: 96vp
Thank you, follow me