www.pudn.com > AVIrep.rar > XAviPlayer.cpp
// XAviPlayer.cpp : Implementation of CXAviPlayer #include "stdafx.h" #include "AVI.h" #include "XAviPlayer.h" #include "commctrl.h" #include///////////////////////////////////////////////////////////////////////////// // CXAviPlayer #define PBM_SETPOS (WM_USER+2) // message loop for our thread. BOOL WaitWithMessageLoop(HANDLE hEvent) { DWORD dwRet; MSG msg; while (1) { dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE, 2000, QS_ALLINPUT); if (dwRet == WAIT_OBJECT_0) { return TRUE; } else if (dwRet == WAIT_OBJECT_0 + 1) { // window message while (PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } else { return FALSE; } } } // thread callback. processes all the dialog stuff. DWORD WINAPI ThreadCallback(CXAviPlayer* pthis) { assert(pthis!=NULL); ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); while (1) { // we have to go now. if (pthis->m_bLast) { if (!pthis->m_pDlg) // should not happen. { SetEvent(pthis->m_hStop); return 1; } Animate_Stop(pthis->m_pDlg->m_hwndAnim); ::DestroyWindow(pthis->m_pDlg->m_hWnd); SetEvent(pthis->m_hStop); // allows ::Stop to procede. ExitThread(0L); return 1L; } // we got the signal to display new additional text. if (pthis->m_bTextNew&&!pthis->m_bFirst) { if (!pthis->m_pDlg) return 1L; // should not happen. HWND hwndControl = ::GetDlgItem(pthis->m_pDlg->m_hWnd, IDC_TEXT); if (hwndControl!=NULL&&pthis->m_pDlg->m_nRows) ::SetWindowText(hwndControl, pthis->m_pDlg->m_sText); pthis->m_bTextNew = FALSE; } // we have to draw the dialog box and initialize all the AVI stuff. if (pthis->m_bFirst) { pthis->m_bFirst = FALSE; HWND hWndTemp = pthis->m_pDlg->Create(NULL); ::SetWindowText(pthis->m_pDlg->m_hWnd, pthis->m_sTitle); ::ShowWindow(pthis->m_pDlg->m_hWnd, SW_SHOW); ::UpdateWindow(pthis->m_pDlg->m_hWnd); // allow ::Play() to procede further. if (pthis->m_hStart) ReleaseMutex(pthis->m_hStart); } else if (!pthis->m_bLast&&pthis->m_pDlg) // right part is a pure precautionary measure. { // it was a mathemetician who designed this formula. double t = (timeGetTime()-(pthis->m_pDlg->m_StartTime))/1000; double c = log(0.5)/(-(pthis->m_pDlg->m_halfLife)); double L = lMaxRange - lMaxRange*exp(-c*t); ::SendMessage(pthis->m_pDlg->m_hwndProgress, PBM_SETPOS, (WPARAM)L, 0); } WaitWithMessageLoop(NULL); // better than sleeping, at least in this routine. } return 1L; } STDMETHODIMP CXAviPlayer::Stop() { if (!m_pDlg) return S_OK; m_bLast = TRUE; // signaling the thread, that we have to go now. WaitForSingleObject(m_hStop, INFINITE); // give him the chance to tidy up. if (m_hThread) { CloseHandle(m_hThread); m_hThread = 0L; } if (m_pDlg) { delete (m_pDlg); m_pDlg = NULL; return S_OK; } return S_FALSE; } CXAviPlayer::~CXAviPlayer() { if (m_hThread) // we have played an AVI. { m_bLast = TRUE; WaitForSingleObject(m_hStop, INFINITE); if (m_pDlg) { ::DestroyWindow(m_pDlg->m_hWnd); delete m_pDlg; m_pDlg = NULL; ATLTRACE(_T("Window destroyed, Pointer deleted.\n")); } } if (m_hStart) { CloseHandle(m_hStart); m_hStart = 0L; } if (m_hStop) { CloseHandle(m_hStop); m_hStop = 0L; } } CXAviPlayer::CXAviPlayer() { m_pDlg = NULL; // vital pointer to dialog box. m_bLast = FALSE; // not stopping now. m_bFirst = FALSE; // but starting at the beginning. m_bTextNew = FALSE; // we don't initial display additional text. m_hStart = CreateMutex(NULL, NULL, NULL); // mutex for synchronizing thread and Play() m_hStop = CreateEvent(NULL, TRUE, FALSE, NULL); // nonsignaled event, which is turned on later. m_hThread = 0L; // on leaving we close the handle. } STDMETHODIMP CXAviPlayer::Play(long hInstance, long hWnd, long ResID, BSTR Title, long Repeat) { // paying tribute to compability. return(PlayEx(hInstance, hWnd, ResID, Title, Repeat, 0, 0, 0, FALSE, 0)); } STDMETHODIMP CXAviPlayer::PlayEx(long hInstance, long hWnd, long ResID, BSTR Title, long Repeat, long Width, long Height, long nTextRows, BOOL Progress, long HalfLife) { USES_CONVERSION; m_bFirst = TRUE; m_sTitle[0] = '\0'; unsigned long len = SysStringLen(Title); len = (len > 255) ? 255 : len; if (len) strncpy(m_sTitle, OLE2A(Title), len); m_sTitle[len] = '\0'; if (ResID < 0) // playing an AVI out of our resource. { switch (ResID) { case -1: ResID = IDR_FILECOPY; break; case -2: ResID = IDR_FILEFIND; break; case -3: ResID = IDR_MAIL; break; case -4: ResID = IDR_PRINT; break; default: return S_FALSE; } if (!strlen(m_sTitle)) LoadString(GetModuleHandle("AVI.dll"), ResID-100, m_sTitle, 255); hInstance = (long)GetModuleHandle("AVI.dll"); } m_pDlg = new CXAviPlay((HINSTANCE)hInstance, ResID, Repeat, Width, Height, nTextRows, Progress, HalfLife, (HWND)hWnd); DWORD ThreadID; if (!m_hStart) { m_hStart = CreateMutex(NULL, NULL, NULL); m_bLast = FALSE; } m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadCallback, (LPVOID)this, 0, &ThreadID); WaitForSingleObject(m_hStart, INFINITE); if (m_hStart) { CloseHandle(m_hStart); m_hStart = 0L; } ATLTRACE("now S_OK\n"); return S_OK; } STDMETHODIMP CXAviPlayer::SetText(BSTR sText) { USES_CONVERSION; if (!m_pDlg) return S_OK; unsigned long len = SysStringLen(sText); len = (len > 255) ? 255 : len; if (len) strncpy(m_pDlg->m_sText, OLE2A(sText), len); m_pDlg->m_sText[len] = '\0'; m_bTextNew = TRUE; return S_OK; } STDMETHODIMP CXAviPlayer::ResetProgressBar() { if (m_pDlg) m_pDlg->ResetProgressBar(); ATLTRACE("Resetting ProgressBar\n"); return S_OK; }