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; 
}