作者: 哈爾濱 潘景巖 --- 在啟動應用程序時演示一段生動的視頻畫面,會使您的軟件增色不少。應該做到演示結束后自動開始主程序;或者在演示過程中,在屏幕上任意位置按下鼠標鍵立即結束演示,并開始主程序。利用Windows提供的 MCIWnd窗口類及宏命令,可方便地創建和開啟視頻窗口,并開始演示。 ---- 需要解決四個問題: ---- 首先,在應用程序視類的構造函數中創建視頻窗口,在初始化函數中開始播放; ---- 其次,建立一個計時器。利用Class Vizard為WM_TIMER增加消息處理函數,以自動關閉視頻窗口并顯示應用程序主窗口; ---- 另外,為了便于從MCIWnd子類化窗口的鼠標消息處理函數中,對應用程序視類的計時器處理函數進行控制,引入一個布爾型全局變量,用來標示是否可以關閉視頻窗口; ---- 最后,也是最關鍵的,應用程序可以截獲發生在主窗口內的鼠標消息,卻無法截獲發生在視頻窗口內的鼠標消息,因為Windows已將視頻窗口的鼠標消息處理函數封裝在MCIWnd窗口類中。所以,為了截獲發生在視頻窗口內的鼠標信息,需要重新定義MCIWnd窗口消息處理函數。 ---- 具體操作步驟如下(在Visual C++6.0環境下調試通過): ---- (1)在應用程序類的頭文件中加入布爾型全局變量: class CMyApp : public CWinApp { public: bool m_CanClose; ... } (2)在應用程序類的構造函數中對這一標志變量進行初始化: CMyApp::CMyApp() { m_CanClose=false; ... } (3)在CMyView類的頭文件中,加入成員変量: private: HWND m_VideoWnd; //視頻窗口句柄 long m_VideoLength; //視頻放映總長度 (4)在MyView.CPP文件中加入以下內容: WNDPROC OldProc; //保存原映射函數 LRESULT CALLBACK NewProc(HWND,UINT, WPARAM,LPARAM); //新映射函數 ... 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(); /* 調用GetWindowLong函數得到 m_VideoWnd窗口原消息處理函數的入口地址, 并保存在OldProc中。*/ OldProc=(WNDPROC) ::GetWindowLong(m_VideoWnd, GWL_WNDPROC); /* 調用SetWindowLong函數將 m_VideoWnd窗口消息處理函數的入口地址改為NewProc */ ::SetWindowLong(m_VideoWnd,GWL_WNDPROC, (LONG)NewProc); m_VideoLength = MCIWndGetLength(m_VideoWnd); //得到視頻放映總長度 MCIWndPlay(m_VideoWnd); //播放視頻文件 SetTimer(1,20,NULL); //建立計時器,每20毫秒激活一次OnTimer函數 } void CJapanView::OnTimer(UINT nIDEvent) { CJapanApp *app=(CJapanApp *)AfxGetApp(); if(MCIWndGetPosition(m_VideoWnd) >=m_VideoLength //自動播放結束 ||app-> m_CanClose==true) //人為按下鼠標左鍵結束 { KillTimer(1); //撤消計時器 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) //鼠標左鍵被按下 { CJapanApp *app=(CJapanApp *)AfxGetApp(); app- >m_CanClose=true; //可以關閉視頻窗口 } //如果不是鼠標左鍵按下消息,則調用原處理函數: return CallWindowProc(OldProc,hWnd, message,wParam,lParam); }
|