wxutil.cpp.svn-base
来自「ffshow源码」· SVN-BASE 代码 · 共 1,177 行 · 第 1/2 页
SVN-BASE
1,177 行
//------------------------------------------------------------------------------// File: WXUtil.cpp//// Desc: DirectShow base classes - implements helper classes for building// multimedia filters.//// Copyright (c) 1992-2002 Microsoft Corporation. All rights reserved.//------------------------------------------------------------------------------#include "stdafx.h"//// Declare function from largeint.h we need so that PPC can build////// Enlarged integer divide - 64-bits / 32-bits > 32-bits//#if !defined(_X86_) || defined(__GNUC__)#define LLtoU64(x) (*(unsigned __int64*)(void*)(&(x)))__inlineULONGWINAPIEnlargedUnsignedDivide ( IN ULARGE_INTEGER Dividend, IN ULONG Divisor, IN PULONG Remainder ){ // return remainder if necessary if (Remainder != NULL) *Remainder = (ULONG)(LLtoU64(Dividend) % Divisor); return (ULONG)(LLtoU64(Dividend) / Divisor);}#else__inlineULONGWINAPIEnlargedUnsignedDivide ( IN ULARGE_INTEGER Dividend, IN ULONG Divisor, IN PULONG Remainder ){ ULONG ulResult; _asm { mov eax,Dividend.LowPart mov edx,Dividend.HighPart mov ecx,Remainder div Divisor or ecx,ecx jz short label mov [ecx],edxlabel: mov ulResult,eax } return ulResult;}#endif// --- CAMEvent -----------------------CAMEvent::CAMEvent(BOOL fManualReset){ m_hEvent = CreateEvent(NULL, fManualReset, FALSE, NULL);}CAMEvent::~CAMEvent(){ if (m_hEvent) { EXECUTE_ASSERT(CloseHandle(m_hEvent)); }}// --- CAMMsgEvent -----------------------// One routine. The rest is handled in CAMEventBOOL CAMMsgEvent::WaitMsg(DWORD dwTimeout){ // wait for the event to be signalled, or for the // timeout (in MS) to expire. allow SENT messages // to be processed while we wait DWORD dwWait; DWORD dwStartTime; // set the waiting period. DWORD dwWaitTime = dwTimeout; // the timeout will eventually run down as we iterate // processing messages. grab the start time so that // we can calculate elapsed times. if (dwWaitTime != INFINITE) { dwStartTime = timeGetTime(); } do { dwWait = MsgWaitForMultipleObjects(1,&m_hEvent,FALSE, dwWaitTime, QS_SENDMESSAGE); if (dwWait == WAIT_OBJECT_0 + 1) { MSG Message; PeekMessage(&Message,NULL,0,0,PM_NOREMOVE); // If we have an explicit length of time to wait calculate // the next wake up point - which might be now. // If dwTimeout is INFINITE, it stays INFINITE if (dwWaitTime != INFINITE) { DWORD dwElapsed = timeGetTime()-dwStartTime; dwWaitTime = (dwElapsed >= dwTimeout) ? 0 // wake up with WAIT_TIMEOUT : dwTimeout-dwElapsed; } } } while (dwWait == WAIT_OBJECT_0 + 1); // return TRUE if we woke on the event handle, // FALSE if we timed out. return (dwWait == WAIT_OBJECT_0);}// --- CAMThread ----------------------CAMThread::CAMThread() : m_EventSend(TRUE) // must be manual-reset for CheckRequest(){ m_hThread = NULL;}CAMThread::~CAMThread() { Close();}// when the thread starts, it calls this function. We unwrap the 'this'//pointer and call ThreadProc.DWORD WINAPICAMThread::InitialThreadProc(LPVOID pv){ HRESULT hrCoInit = CAMThread::CoInitializeHelper(); if(FAILED(hrCoInit)) { DbgLog((LOG_ERROR, 1, TEXT("CoInitializeEx failed."))); } CAMThread * pThread = (CAMThread *) pv; HRESULT hr = pThread->ThreadProc(); if(SUCCEEDED(hrCoInit)) { CoUninitialize(); } return hr;}BOOLCAMThread::Create(){ DWORD threadid; CAutoLock lock(&m_AccessLock); if (ThreadExists()) { return FALSE; } m_hThread = CreateThread( NULL, 0, CAMThread::InitialThreadProc, this, 0, &threadid); if (!m_hThread) { return FALSE; } return TRUE;}DWORDCAMThread::CallWorker(DWORD dwParam){ // lock access to the worker thread for scope of this object CAutoLock lock(&m_AccessLock); if (!ThreadExists()) { return (DWORD) E_FAIL; } // set the parameter m_dwParam = dwParam; // signal the worker thread m_EventSend.Set(); // wait for the completion to be signalled m_EventComplete.Wait(); // done - this is the thread's return value return m_dwReturnVal;}// Wait for a request from the clientDWORDCAMThread::GetRequest(){ m_EventSend.Wait(); return m_dwParam;}// is there a request?BOOLCAMThread::CheckRequest(DWORD * pParam){ if (!m_EventSend.Check()) { return FALSE; } else { if (pParam) { *pParam = m_dwParam; } return TRUE; }}// reply to the requestvoidCAMThread::Reply(DWORD dw){ m_dwReturnVal = dw; // The request is now complete so CheckRequest should fail from // now on // // This event should be reset BEFORE we signal the client or // the client may Set it before we reset it and we'll then // reset it (!) m_EventSend.Reset(); // Tell the client we're finished m_EventComplete.Set();}HRESULT CAMThread::CoInitializeHelper(){ // call CoInitializeEx and tell OLE not to create a window (this // thread probably won't dispatch messages and will hang on // broadcast msgs o/w). // // If CoInitEx is not available, threads that don't call CoCreate // aren't affected. Threads that do will have to handle the // failure. Perhaps we should fall back to CoInitialize and risk // hanging? // // older versions of ole32.dll don't have CoInitializeEx HRESULT hr = E_FAIL; HINSTANCE hOle = GetModuleHandle(TEXT("ole32.dll")); if(hOle) { typedef HRESULT (STDAPICALLTYPE *PCoInitializeEx)( LPVOID pvReserved, DWORD dwCoInit); PCoInitializeEx pCoInitializeEx = (PCoInitializeEx)(GetProcAddress(hOle, "CoInitializeEx")); if(pCoInitializeEx) { hr = (*pCoInitializeEx)(0, COINIT_DISABLE_OLE1DDE ); } } else { // caller must load ole32.dll DbgBreak("couldn't locate ole32.dll"); } return hr;}#if 0// destructor for CMsgThread - cleans up any messages left in the// queue when the thread exitedCMsgThread::~CMsgThread(){ if (m_hThread != NULL) { WaitForSingleObject(m_hThread, INFINITE); EXECUTE_ASSERT(CloseHandle(m_hThread)); } POSITION pos = m_ThreadQueue.GetHeadPosition(); while (pos) { CMsg * pMsg = m_ThreadQueue.GetNext(pos); delete pMsg; } m_ThreadQueue.RemoveAll(); if (m_hSem != NULL) { EXECUTE_ASSERT(CloseHandle(m_hSem)); }}BOOLCMsgThread::CreateThread( ){ m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); if (m_hSem == NULL) { return FALSE; } m_hThread = ::CreateThread(NULL, 0, DefaultThreadProc, (LPVOID)this, 0, &m_ThreadId); return m_hThread != NULL;}// This is the threads message pump. Here we get and dispatch messages to// clients thread proc until the client refuses to process a message.// The client returns a non-zero value to stop the message pump, this// value becomes the threads exit code.DWORD WINAPICMsgThread::DefaultThreadProc( LPVOID lpParam ){ CMsgThread *lpThis = (CMsgThread *)lpParam; CMsg msg; LRESULT lResult; // !!! CoInitialize(NULL); // allow a derived class to handle thread startup lpThis->OnThreadInit(); do { lpThis->GetThreadMsg(&msg); lResult = lpThis->ThreadMessageProc(msg.uMsg,msg.dwFlags, msg.lpParam, msg.pEvent); } while (lResult == 0L); // !!! CoUninitialize(); return (DWORD)lResult;}// Block until the next message is placed on the list m_ThreadQueue.// copies the message to the message pointed to by *pmsgvoidCMsgThread::GetThreadMsg(CMsg *msg){ CMsg * pmsg = NULL; // keep trying until a message appears while (TRUE) { { CAutoLock lck(&m_Lock); pmsg = m_ThreadQueue.RemoveHead(); if (pmsg == NULL) { m_lWaiting++; } else { break; } } // the semaphore will be signalled when it is non-empty WaitForSingleObject(m_hSem, INFINITE); } // copy fields to caller's CMsg *msg = *pmsg; // this CMsg was allocated by the 'new' in PutThreadMsg delete pmsg;}#endif// NOTE: as we need to use the same binaries on Win95 as on NT this code should// be compiled WITHOUT unicode being defined. Otherwise we will not pick up// these internal routines and the binary will not run on Win95.#ifndef UNICODE// Windows 95 doesn't implement this, so we provide an implementation.LPWSTRWINAPIlstrcpyWInternal( LPWSTR lpString1, LPCWSTR lpString2 ){ LPWSTR lpReturn = lpString1; while (*lpString1++ = *lpString2++); return lpReturn;}// Windows 95 doesn't implement this, so we provide an implementation.LPWSTRWINAPIlstrcpynWInternal( LPWSTR lpString1, LPCWSTR lpString2, int iMaxLength ){ ASSERT(iMaxLength); LPWSTR lpReturn = lpString1; if (iMaxLength) { while (--iMaxLength && (*lpString1++ = *lpString2++)); // If we ran out of room (which will be the case if // iMaxLength is now 0) we still need to terminate the // string. if (!iMaxLength) *lpString1 = L'\0'; } return lpReturn;}intWINAPIlstrcmpWInternal( LPCWSTR lpString1, LPCWSTR lpString2 ){ do { WCHAR c1 = *lpString1; WCHAR c2 = *lpString2; if (c1 != c2) return (int) c1 - (int) c2; } while (*lpString1++ && *lpString2++); return 0;}intWINAPIlstrcmpiWInternal( LPCWSTR lpString1, LPCWSTR lpString2 ){ do { WCHAR c1 = *lpString1; WCHAR c2 = *lpString2; if (c1 >= L'A' && c1 <= L'Z') c1 -= (WCHAR) (L'A' - L'a'); if (c2 >= L'A' && c2 <= L'Z') c2 -= (WCHAR) (L'A' - L'a'); if (c1 != c2) return (int) c1 - (int) c2; } while (*lpString1++ && *lpString2++); return 0;}intWINAPIlstrlenWInternal( LPCWSTR lpString ){ int i = -1; while (*(lpString+(++i))) ; return i;}int WINAPIV wsprintfWInternal(LPWSTR wszOut, LPCWSTR pszFmt, ...){ char fmt[256]; // !!! char ach[256]; // !!! int i; va_list va; va_start(va, pszFmt); WideCharToMultiByte(GetACP(), 0, pszFmt, -1, fmt, 256, NULL, NULL); i = wvsprintfA(ach, fmt, va); va_end(va); MultiByteToWideChar(CP_ACP, 0, ach, -1, wszOut, i+1); return i;}#else// need to provide the implementations in unicode for non-unicode// builds linking with the unicode strmbase.libLPWSTR WINAPI lstrcpyWInternal( LPWSTR lpString1, LPCWSTR lpString2 ){ return lstrcpyW(lpString1, lpString2);}LPWSTR WINAPI lstrcpynWInternal( LPWSTR lpString1, LPCWSTR lpString2, int iMaxLength ){ return lstrcpynW(lpString1, lpString2, iMaxLength);}int WINAPI lstrcmpWInternal( LPCWSTR lpString1, LPCWSTR lpString2 ){ return lstrcmpW(lpString1, lpString2);}int WINAPI lstrcmpiWInternal( LPCWSTR lpString1, LPCWSTR lpString2 ){ return lstrcmpiW(lpString1, lpString2);}int WINAPI lstrlenWInternal( LPCWSTR lpString ){ return lstrlenW(lpString);}int WINAPIV wsprintfWInternal( LPWSTR wszOut, LPCWSTR pszFmt, ...){ va_list va; va_start(va, pszFmt); int i = wvsprintfW(wszOut, pszFmt, va); va_end(va); return i;}#endif// Helper function - convert int to WSTRvoid WINAPI IntToWstr(int i, LPWSTR wstr){#ifdef UNICODE wsprintf(wstr, L"%d", i);#else TCHAR temp[32]; wsprintf(temp, "%d", i); MultiByteToWideChar(CP_ACP, 0, temp, -1, wstr, 32);#endif} // IntToWstr#if 0void * memchrInternal(const void *pv, int c, size_t sz){ BYTE *pb = (BYTE *) pv; while (sz--) { if (*pb == c) return (void *) pb; pb++; } return NULL;}#endif/* Arithmetic functions to help with time format conversions*//* Compute (a * b + d) / c */LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG d)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?