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 + -
显示快捷键?