作者: 哈爾濱 潘景巖 --- 在啟動(dòng)應(yīng)用程序時(shí)演示一段生動(dòng)的視頻畫面,會(huì)使您的軟件增色不少。應(yīng)該做到演示結(jié)束后自動(dòng)開始主程序;或者在演示過程中,在屏幕上任意位置按下鼠標(biāo)鍵立即結(jié)束演示,并開始主程序。利用Windows提供的 MCIWnd窗口類及宏命令,可方便地創(chuàng)建和開啟視頻窗口,并開始演示。 ---- 需要解決四個(gè)問題: ---- 首先,在應(yīng)用程序視類的構(gòu)造函數(shù)中創(chuàng)建視頻窗口,在初始化函數(shù)中開始播放; ---- 其次,建立一個(gè)計(jì)時(shí)器。利用Class Vizard為WM_TIMER增加消息處理函數(shù),以自動(dòng)關(guān)閉視頻窗口并顯示應(yīng)用程序主窗口; ---- 另外,為了便于從MCIWnd子類化窗口的鼠標(biāo)消息處理函數(shù)中,對(duì)應(yīng)用程序視類的計(jì)時(shí)器處理函數(shù)進(jìn)行控制,引入一個(gè)布爾型全局變量,用來標(biāo)示是否可以關(guān)閉視頻窗口; ---- 最后,也是最關(guān)鍵的,應(yīng)用程序可以截獲發(fā)生在主窗口內(nèi)的鼠標(biāo)消息,卻無法截獲發(fā)生在視頻窗口內(nèi)的鼠標(biāo)消息,因?yàn)閃indows已將視頻窗口的鼠標(biāo)消息處理函數(shù)封裝在MCIWnd窗口類中。所以,為了截獲發(fā)生在視頻窗口內(nèi)的鼠標(biāo)信息,需要重新定義MCIWnd窗口消息處理函數(shù)。 ---- 具體操作步驟如下(在Visual C++6.0環(huán)境下調(diào)試通過): ---- (1)在應(yīng)用程序類的頭文件中加入布爾型全局變量: class CMyApp : public CWinApp { public: bool m_CanClose; ... } (2)在應(yīng)用程序類的構(gòu)造函數(shù)中對(duì)這一標(biāo)志變量進(jìn)行初始化: CMyApp::CMyApp() { m_CanClose=false; ... } (3)在CMyView類的頭文件中,加入成員変量: private: HWND m_VideoWnd; //視頻窗口句柄 long m_VideoLength; //視頻放映總長度 (4)在MyView.CPP文件中加入以下內(nèi)容: WNDPROC OldProc; //保存原映射函數(shù) LRESULT CALLBACK NewProc(HWND,UINT, WPARAM,LPARAM); //新映射函數(shù) ... CMyView::CMyView() { CString filename("D:\\Video\\Cover.avi"); //建立視頻窗口,并將句柄保存在m_VideoWnd中: m_VideoWnd = MCIWndCreate( this- >GetSafeHwnd(), AfxGetInstanceHandle(), WS_POPUP|WS_VISIBLE| MCIWNDF_NOPLAYBAR| MCIWNDF_NOMENU, filename); //使視頻窗口在屏幕上居中顯示: RECT rect; int sx,sy; ::GetWindowRect(m_VideoWnd,&rect); sx=(::GetSystemMetrics(SM_CXSCREEN) -rect.right+rect.left)/2; sy=(::GetSystemMetrics(SM_CYSCREEN) -rect.bottom+rect.top)/2; ::SetWindowPos(m_VideoWnd,HWND_TOPMOST,sx, sy,0,0,SWP_SHOWWINDOW|SWP_NOSIZE); } void CMyView::OnInitialUpdate() { CView::OnInitialUpdate(); /* 調(diào)用GetWindowLong函數(shù)得到 m_VideoWnd窗口原消息處理函數(shù)的入口地址, 并保存在OldProc中。*/ OldProc=(WNDPROC) ::GetWindowLong(m_VideoWnd, GWL_WNDPROC); /* 調(diào)用SetWindowLong函數(shù)將 m_VideoWnd窗口消息處理函數(shù)的入口地址改為NewProc */ ::SetWindowLong(m_VideoWnd,GWL_WNDPROC, (LONG)NewProc); m_VideoLength = MCIWndGetLength(m_VideoWnd); //得到視頻放映總長度 MCIWndPlay(m_VideoWnd); //播放視頻文件 SetTimer(1,20,NULL); //建立計(jì)時(shí)器,每20毫秒激活一次OnTimer函數(shù) } void CJapanView::OnTimer(UINT nIDEvent) { CJapanApp *app=(CJapanApp *)AfxGetApp(); if(MCIWndGetPosition(m_VideoWnd) >=m_VideoLength //自動(dòng)播放結(jié)束 ||app-> m_CanClose==true) //人為按下鼠標(biāo)左鍵結(jié)束 { KillTimer(1); //撤消計(jì)時(shí)器 MCIWndDestroy(m_VideoWnd); //撤消視頻窗口 AfxGetMainWnd()- >ShowWindow(SW_SHOWMAXIMIZED); //顯示主窗口 } CRecordView::OnTimer(nIDEvent); } LRESULT CALLBACK NewProc(HWND hWnd,UINT message, WPARAM wParam,LPARAM lParam) { if(message==WM_LBUTTONDOWN) //鼠標(biāo)左鍵被按下 { CJapanApp *app=(CJapanApp *)AfxGetApp(); app- >m_CanClose=true; //可以關(guān)閉視頻窗口 } //如果不是鼠標(biāo)左鍵按下消息,則調(diào)用原處理函數(shù): return CallWindowProc(OldProc,hWnd, message,wParam,lParam); }
|