北京时间23点11分 2018年12月20日
前面已经完成了vlc的环境的搭建,下面便开始真正的编程。
前面的界面是这样的:
理想的界面应该是这样的:
所以添加按钮、进度条和播放列表控件,并且修改好ID。
界面设计完成,运行,还是只是一个空壳,因为没加任何处理函数。
接下来就要实现拖拽文件或者文件夹到对话框时,自动添加路径到播放列表控件上。
首先先把对话框属性中的Accept Files设为TRUE,然后再设置消息处理函数。
在类向导里面添加文件拖拽响应信息
在OnDropFiles里面添加一下处理函数
void CVlcPlayerCsdnDlg::OnDropFiles(HDROP hDropInfo)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
UINT nFileCount = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);
TCHAR szFileName[_MAX_PATH] = _T("");
CFileStatus fStatus;
CStringArray strArray;
ShowPlaylist(TRUE);
// 获取拖拽进来文件和文件夹
for (UINT i = 0; i < nFileCount; i++)
{
// 获取文件路径
::DragQueryFile(hDropInfo, i, szFileName, sizeof(szFileName));
CFile::GetStatus(szFileName, fStatus);
// 是否为文件夹
if (fStatus.m_attribute & FILE_ATTRIBUTE_DIRECTORY)
{
::SetCurrentDirectory(szFileName); // 将当前目录设置在此
EnumerateFiles(strArray); // 枚举目录中所有文件
}
else
{
strArray.Add(szFileName);
}
}
// 过滤需要的文件
m_listPlay.SetRedraw(FALSE);
m_listPlay.SetHorizontalExtent(1500); // 这里只是简单的设置为500宽度,若要刚好匹配路径宽度,请参见msdn里的例子
for (int i = 0; i < strArray.GetCount(); i++)
{
if (IsWantedFile(strArray[i]))
{
m_listPlay.AddString(strArray[i]);
}
}
m_listPlay.SetRedraw(TRUE);
::DragFinish(hDropInfo);
CDialog::OnDropFiles(hDropInfo);
}
其中,用到的m_listPlay变量为播放列表控件变量,m_listInfo为音频显示控件信息的控件变量。
EnumerateFiles的函数定义为:
void EnumerateFiles(CStringArray &strArray)
{
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(_T("*.*"), &fd);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
// 如果为目录
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// 如果不为当前目录.或上一层目录..
if (_tcscmp(fd.cFileName, _T(".")) && _tcscmp(fd.cFileName, _T("..")))
{
::SetCurrentDirectory(fd.cFileName); // 进入该目录
EnumerateFiles(strArray); // 递归枚举
::SetCurrentDirectory(_T("..")); // 返回该目录上一层目录
}
}
// 如果为文件
else
{
CString strDir;
TCHAR lpDir[MAX_PATH];
::GetCurrentDirectory(MAX_PATH, lpDir);
strDir = lpDir;
if (strDir.Right(1) != _T("\\"))
{
strDir += _T("\\");
}
strDir += fd.cFileName;
strArray.Add(strDir);
}
} while (::FindNextFile(hFind, &fd));
::FindClose(hFind);
}
}
IsWantedFile的函数定义为:
BOOL IsWantedFile(const CString &str)
{
CString strLower;
TCHAR szExt[_MAX_EXT] = _T("");
const CString STR_FileFilter =
_T("*.rm;*.rmvb;*.flv;*.f4v;*.avi;*.3gp;*.mp4;*.wmv;*.mpeg;*.mpga;*.asf;*.dat;*.mov;*.mkv;*")
_T("*.mp3;*.wma;*.wav;*.mid;*.rmi;*.aac;*.ac3;*.aiff;*.m4a;*.mka;*.mp2;*.ogg;*");
_tsplitpath_s(str, NULL, 0, NULL, 0, NULL, 0, szExt, _MAX_EXT); // 获取后缀名
strLower = szExt;
strLower.MakeLower();
if (!strLower.IsEmpty()) // 没有后缀名的不符合条件
{
strLower += _T(";*"); // .mo不符合条件,由于会匹配到.mov,所以在后面加上【;*】来判断是否完全匹配
return -1 != STR_FileFilter.Find(strLower);
}
return FALSE;
}
ShowPlaylist的定义为:
void CVlcPlayerCsdnDlg::ShowPlaylist(BOOL bShow)
{
CRect rcWnd, rcPlaylist;
GetWindowRect(&rcWnd);
m_listPlay.GetClientRect(&rcPlaylist);
if (m_listPlay.IsWindowVisible() != bShow) // 只有显示状态发生变化时,才调整窗口大小
{
if (bShow)
{
SetWindowPos(NULL, 0, 0, rcWnd.Width() + rcPlaylist.Width(), rcWnd.Height(), SWP_NOMOVE);
}
else
{
SetWindowPos(NULL, 0, 0, rcWnd.Width() - rcPlaylist.Width(), rcWnd.Height(), SWP_NOMOVE);
}
}
m_listPlay.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
m_listInfo.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
}
运行,如下:
最后的最后,再实现一下一开始隐藏播放列表的功能。
在初始化函数隐藏,代码为:
CRect rcWnd, rcPlaylist;
GetWindowRect(&rcWnd);
m_listPlay.GetClientRect(&rcPlaylist);
SetWindowPos(NULL, 0, 0, rcWnd.Width() - rcPlaylist.Width() - GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXBORDER), rcWnd.Height() , SWP_NOMOVE);
GetDlgItem(IDC_LIST_PLAY)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_LIST_MUSINFO)->ShowWindow(SW_HIDE);
好了,运行,播放列表已经隐藏:
拖拽如文件后,播放列表再次显示:
行了,运行完成!
代码已经上传,你们可以看一下。下载地址
注意:1、本人是萌新,大佬们可以直接跳过阅读我的文章,写这个目的就是为了赚点分数以后可以用,当然也是想和其他萌新一起学习。
2、我会尽力快点更新,如果有什么问题大家可以在底下评论,我看到便会回复的,我的个人邮箱[email protected]
3、每一期我都会尽量放上源代码,希望能帮到大家的学习。