MFC 基於VLC的視訊播放器(三)---介面設計以及對話方塊接受檔案的拖拽
阿新 • • 發佈:2018-12-27
北京時間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、每一期我都會盡量放上原始碼,希望能幫到大家的學習。