這段時間在使用MFC做媒體播放器項目,查詢了不少資料,用到的技術主要有ADO、多線程、DirectShow、MFC相關控制項包括ActiveX控制項(Windows Media Player、Active Movie3)的使用等等一些東西。用的主要參考文檔有Windows Media Player相關的開發文檔、MSDN。
先談一下這段時間的收穫吧,這將近一個月的時間內,通過媒體播放器項目,我熟悉了使用ADO操作Access資料庫、SQL語句的運用(雖然用的語句比較簡單,無非增刪改查)、Window Media Player對應的17個類的使用、MFC的列表框CListBox、樹控制項CTreeCtrl、CListCtrl等控制項、多線程的使用等。接下來把自己查詢搜集到的資料做一個整理吧(主要是通過查詢csdn、部落格園、百度文庫找到的)。
1、VC擷取一個菜單的狀態,並打鉤
做記事本的時候,遇到這麼個問題,就是:如何擷取功能表項目當前是否被選中(打勾),如果選中,點擊菜單後取消選中,如果未選中,點擊菜單後選中,具體實現代碼如下:
void CMyNotePadDlg::OnStatus() //菜單的Command訊息映射函數
{
// TODO: Add your command handler code here
if (AfxGetMainWnd()->GetMenu()->GetMenuState(ID_STATUS,MF_CHECKED))
{
AfxGetMainWnd()->GetMenu()->CheckMenuItem(ID_STATUS,MF_UNCHECKED);
}
else
{
AfxGetMainWnd()->GetMenu()->CheckMenuItem(ID_STATUS,MF_CHECKED);
}
}
2、VC中隱藏視窗的一部分,比如說查詢資料庫的左右側視窗、播放清單顯示部分等。
代碼如下:
void CMyMediaPlayerDlg::OnButtonHide()
{
// TODO: Add your control notification handler code here
CString str;
if (GetDlgItemText(IDC_BUTTON_HIDE,str),str=="<<")
{
SetDlgItemText(IDC_BUTTON_HIDE,">>");
}
else
{
SetDlgItemText(IDC_BUTTON_HIDE,"<<");
}
static CRect rectLarge;
static CRect rectSmall;
if(rectLarge.IsRectNull())
{
CRect rectSeparator;
GetWindowRect(&rectLarge);
GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSeparator);
rectSmall.left=rectLarge.left;
rectSmall.top=rectLarge.top;
rectSmall.right=rectSeparator.right;
rectSmall.bottom=rectLarge.bottom;
}
if (str=="<<")
{
SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height(),SWP_NOMOVE | SWP_NOZORDER);
}
else
{
SetWindowPos(NULL,0,0,rectLarge.Width(),rectLarge.Height(),SWP_NOMOVE | SWP_NOZORDER);
}
}
3、如何給指定的對話方塊添加菜單?
犯法1:靜態載入菜單,即不通過代碼而是通過編輯資源。
轉至對話方塊資源,在需要添加菜單的對話方塊資源IDD_MYMEDIAPLAYER_DIALOG中,選中該對話方塊資源,右鍵選擇【Properties】屬性,再在【General】選項卡的Menu中選擇需要添加的菜單,比如IDR_MAINFRAME_MENU,這樣的話就可以在該對話方塊類對象建立時使用時就可以顯示該菜單了。
這樣就將菜單和對話方塊關聯起來了。
方法2:直接通過代碼載入菜單
在的對話方塊類的OnInitDialog()函數中加這麼幾行代碼就搞定了。
//載入菜單
CMenu menu;
menu.LoadMenu(IDR_MENU1);
SetMenu(&menu);
4、MFC中各種指標的擷取
VC中編程對於剛剛開始學習的同學,最大的障礙和問題就是訊息機制和指標擷取與操作。其實這些內容基本上是每本VC學習工具書上必講的內容,而且通過MSDN很多問題都能解決。一般我們使用的架構是VC提供的Wizard產生的MFC App Wizard(exe)架構,無論是多文檔還是單文檔,都存在指標擷取和操作問題。下面這節內容主要是一般的架構,然後再講多線程中的指標使用。使用到的類需要包含響應的標頭檔。首先一般獲得本類(視,文檔,對話方塊都支援)執行個體指標this,用this的目的,主要可以通過類中的函數向其他類或者函數中髮指針,以便於在非本類中操作和使用本類中的
功能。
目錄:
1) 在View中獲得Doc指標
2) 在App中獲得MainFrame指標
3) 在View中獲得MainFrame指標
4) 獲得View(已建立)指標
5) 獲得當前文檔指標
6) 獲得狀態列與工具列指標
7) 獲得狀態列與工具列變數
8) 在Mainframe獲得菜單指標
9) 在任何類中獲得應用程式類
10) 從文檔類取得視圖類的指標
1) 在View中獲得Doc指標
CYouSDIDoc *pDoc=GetDocument();一個視只能有一個文檔。
2) 在App中獲得MainFrame指標
CWinApp 中的 m_pMainWnd變數就是MainFrame的指標
也可以: CMainFrame *pMain =(CMainFrame *)AfxGetMainWnd();
3) 在View中獲得MainFrame指標
CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;
4) 獲得View(已建立)指標
CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;
CyouView *pView=(CyouView *)pMain->GetActiveView();
5) 獲得當前文檔指標
CDocument * pCurrentDoc =(CFrameWnd *)m_pMainWnd->GetActiveDocument();
6) 獲得狀態列與工具列指標
CStatusBar * pStatusBar=(CStatusBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
CToolBar * pToolBar=(CtoolBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR);
7) 如果架構中加入工具列和狀態列變數還可以這樣
(CMainFrame *)GetParent()->m_wndToolBar;
(CMainFrame *)GetParent()->m_wndStatusBar;
8) 在Mainframe獲得菜單指標
CMenu *pMenu=m_pMainWnd->GetMenu();
9) 在任何類中獲得應用程式類
用MFC全域函數AfxGetApp()獲得。
10) 從文檔類取得視圖類的指標
從文檔獲得視圖類指標目的一般為了控制同一文檔的多個視圖的定位問題,我的體會特別是文文書處理CEditView當產生多個視圖類時,這個功能是非常需要的。
CDocument類提供了兩個函數用於視圖類的定位:
GetFirstViewPosition()和GetNextView()
virtual POSITION GetFirstViewPosition() const;
virtual CView* GetNextView(POSITION& rPosition) const;
5、MFC的檔案操作 檔案開啟對話方塊類CFileDialoag和CFile檔案類的使用
(1)、建立開啟檔案對話方塊:
CFileDialog dlg(TRUE,//TRUE是建立開啟檔案對話方塊,FALSE則建立的是儲存檔案對話方塊
".txt",//預設的開啟檔案的類型
NULL,//預設開啟的檔案名稱
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,//開啟唯讀檔案
"文字檔(*.txt)|*.txt|所有檔案 (*.*)|*.*||");//所有可以開啟的檔案類型
(2).點開啟檔案對話方塊上面的確定鍵後
if(dlg.DoModal()==IDOK)
{
CString m_FilePath = dlg.GetPathName();////////取出檔案路徑
CString m_path;
m_path=m_FilePath;//將檔案的路徑放入m_path
UpdateData(FALSE);
}
(3).開啟檔案:
CFile File;
File.Open(m_path,CFile::modeRead);
(4).逐行讀取檔案: CStdioFile File;///可以逐行讀檔案的類
CString strLine;
while(File.ReadString(strLine)) //////將每行都放進strLine字串裡
{
AfxMessgeBox(strLine);
}
(5)、判斷讀出來的字:
strLine=“1|2|3|”;//要判斷的字串
int strIndex1 = strLine.Find('|');//在字串中尋找“|”
CString a[11];
if(-1 != strIndex1)//只要找到“|”就不會返回-1
{
int i=0;
while( -1 != strIndex1)//
{
strIndex1 = strLine.Find('|');
a[i] = strLine.Left(strIndex1);
strLine = strLine.Right(strLine.GetLength() - strIndex1-1) ;
i++;
if (i > 10)//退出迴圈
break;
}
}
}
6、VC擷取本地目前時間
(1).自訂函數:void MyGetDateTime ( char * buff )
{
WORD sYear,sMonth,sDay,sHour,sMinute,sSecond;
SYSTEMTIME CurTime;/////定義SYSTEMTIME類的對象
GetLocalTime(&CurTime);////擷取本地時間
sYear=CurTime.wYear;////獲得年
sM.wMonth;//獲得月
sDay=CurTime.wDay;
sHour=CurTime.wHour;
sMinute=CurTime.wMinute;
sSec.wSecond;
sprintf(buff,"%d,%d,%d,%d,%d,%d",sYear,sMonth,sDay,sHour,sMinute,sSecond);///將年月日時分秒放進buff裡
}
(2).調用時:
char b[20];
MyGetDateTime(b);////數組名字其實就是指標
7、MFC檔案對話方塊 開啟多個檔案
try
{
CString str("",10000);//這是做為存放開啟檔案名稱和路徑的字串空間10000這個值的設定就覺得有些不妥當
CFileDialog openfile(true,NULL,NULL,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT,"All Files(*.*)|*.*|",AfxGetMainWnd());
openfile.m_ofn.lpstrFile=str.GetBuffer(10000);
openfile.m_ofn.nMaxFile=10000;
openfile.m_ofn.lStructSize=sizeof(openfile.m_ofn);
CString pathname("",MAX_PATH);
CFileStatus status;
openfile.DoModal();
POSITION mPos=openfile.GetStartPosition();
while(mPos!=NULL){
pathname=openfile.GetNextPathName(mPos);
CFile::GetStatus(pathname,status);
this->m_listresult.InsertItem(count++,pathname); //把包括路徑在內的檔案名稱寫到一個list控制項裡
}
}
catch (CException* e)
{
AfxMessageBox(_T("開啟檔案出錯了!"));
e->Delete();
}
if (fileDialog.DoModal() == IDOK)
{
CString fileName;//=fileDialog.GetPathName();
//m_MediaPlayer.put_URL(fileName);
int m_countitem = m_ListCtrl.GetItemCount();
POSITION pos = fileDialog.GetStartPosition();
for (;pos != NULL;)
{
//CString m_FileName = fileDialog.GetFileName();
fileName = fileDialog.GetNextPathName(pos);
//CString str="C:C:MyProjectmy.exe";
int npos=fileName.ReverseFind('');
CString m_FileName=fileName.Mid(npos+1);
}
8、VS2005以上版本中CString轉換成char數組的一個有效方法
使用API函數WideCharToMultiByte
常式如下:
CString fileName;
char strfileName[200] = {0};
WideCharToMultiByte(CP_ACP,0,(LPCTSTR)fileName,-1,strfileName,200,NULL,NULL);
9、遍曆檔案夾及其子檔案夾
使用MFC提供的FileFind類FindFile/FileNextFile()等成員函數。
代碼如下:
void ScanFile(CString Dir)
{
CFileFind finder;
CString Add=L"\*";
CString DirSpec=Dir+Add; //補全要遍曆的檔案夾的目錄
BOOL bWorking = finder.FindFile(DirSpec);
while (bWorking)
{
bWorking = finder.FindNextFile();
if(!finder.IsDots()) //掃描到的不是節點
{
if(finder.IsDirectory()) //掃描到的是檔案夾
{
CString strDirectory = finder.GetFilePath();
ScanFile(strDirectory); //遞迴調用ScanFile()
}
else //掃描到的是檔案
{
//CString strFile = finder.GetFilePath(); 得到檔案的全路徑
//進行一系列自訂動作
}
}
}
finder.Close();
}
最後特別要感謝那些前輩們,謝謝你們的文章和代碼,這讓我學到了不少東西。
再推薦幾個IT網站吧,我經常逛的。
CSDN:這個就不用我多說了吧。傳說中最大的IT中文社區,資源和文章都不錯,就是代碼品質上可能差了點。
程式員聯合開發網:http://www.pudn.com,最大的源碼下載中文網站,唯一的痛點就是要上傳原始碼或者資料後才能成為會員,代碼品質總體來說比csdn要好。
如鵬網:http://www.rupeng.com,雖說是針對在校大學生的,但是有些東西還是比較好,注重基礎。
http://www.codeforge.com:一個英文開放原始碼分享網站,聽說下載代碼不要積分,註冊即可。
http://www.codeproject.com/:一個英文網站,包括代碼、問題解答之類的,個人感覺還不錯。
http://www.javaeye.com/:一個Java學習的網站。
http://bbs.chinaunix.net:ChinaUnix學習社區
http://my.oschina.net:開源中國社區
但願以上的網站對大家有協助吧。