wxutil.cpp.svn-base
来自「ffshow源码」· SVN-BASE 代码 · 共 1,177 行 · 第 1/2 页
SVN-BASE
1,177 行
{ /* Compute the absolute values to avoid signed arithmetic problems */ ULARGE_INTEGER ua, ub; DWORDLONG uc; ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a); ub.QuadPart = (DWORDLONG)(b >= 0 ? b : -b); uc = (DWORDLONG)(c >= 0 ? c : -c); BOOL bSign = (a < 0) ^ (b < 0); /* Do long multiplication */ ULARGE_INTEGER p[2]; p[0].QuadPart = UInt32x32To64(ua.LowPart, ub.LowPart); /* This next computation cannot overflow into p[1].HighPart because the max number we can compute here is: (2 ** 32 - 1) * (2 ** 32 - 1) + // ua.LowPart * ub.LowPart (2 ** 32) * (2 ** 31) * (2 ** 32 - 1) * 2 // x.LowPart * y.HighPart * 2 == 2 ** 96 - 2 ** 64 + (2 ** 64 - 2 ** 33 + 1) == 2 ** 96 - 2 ** 33 + 1 < 2 ** 96 */ ULARGE_INTEGER x; x.QuadPart = UInt32x32To64(ua.LowPart, ub.HighPart) + UInt32x32To64(ua.HighPart, ub.LowPart) + p[0].HighPart; p[0].HighPart = x.LowPart; p[1].QuadPart = UInt32x32To64(ua.HighPart, ub.HighPart) + x.HighPart; if (d != 0) { ULARGE_INTEGER ud[2]; if (bSign) { ud[0].QuadPart = (DWORDLONG)(-d); if (d > 0) { /* -d < 0 */ ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1; } else { ud[1].QuadPart = (DWORDLONG)0; } } else { ud[0].QuadPart = (DWORDLONG)d; if (d < 0) { ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1; } else { ud[1].QuadPart = (DWORDLONG)0; } } /* Now do extended addition */ ULARGE_INTEGER uliTotal; /* Add ls DWORDs */ uliTotal.QuadPart = (DWORDLONG)ud[0].LowPart + p[0].LowPart; p[0].LowPart = uliTotal.LowPart; /* Propagate carry */ uliTotal.LowPart = uliTotal.HighPart; uliTotal.HighPart = 0; /* Add 2nd most ls DWORDs */ uliTotal.QuadPart += (DWORDLONG)ud[0].HighPart + p[0].HighPart; p[0].HighPart = uliTotal.LowPart; /* Propagate carry */ uliTotal.LowPart = uliTotal.HighPart; uliTotal.HighPart = 0; /* Add MS DWORDLONGs - no carry expected */ p[1].QuadPart += ud[1].QuadPart + uliTotal.QuadPart; /* Now see if we got a sign change from the addition */ if ((LONG)p[1].HighPart < 0) { bSign = !bSign; /* Negate the current value (ugh!) */ p[0].QuadPart = ~p[0].QuadPart; p[1].QuadPart = ~p[1].QuadPart; p[0].QuadPart += 1; p[1].QuadPart += (p[0].QuadPart == 0); } } /* Now for the division */ if (c < 0) { bSign = !bSign; } /* This will catch c == 0 and overflow */ if (uc <= p[1].QuadPart) { return bSign ? (LONGLONG)0x8000000000000000LL : (LONGLONG)0x7FFFFFFFFFFFFFFFLL; } DWORDLONG ullResult; /* Do the division */ /* If the dividend is a DWORD_LONG use the compiler */ if (p[1].QuadPart == 0) { ullResult = p[0].QuadPart / uc; return bSign ? -(LONGLONG)ullResult : (LONGLONG)ullResult; } /* If the divisor is a DWORD then its simpler */ ULARGE_INTEGER ulic; ulic.QuadPart = uc; if (ulic.HighPart == 0) { ULARGE_INTEGER uliDividend; ULARGE_INTEGER uliResult; DWORD dwDivisor = (DWORD)uc; // ASSERT(p[1].HighPart == 0 && p[1].LowPart < dwDivisor); uliDividend.HighPart = p[1].LowPart; uliDividend.LowPart = p[0].HighPart;#ifndef USE_LARGEINT uliResult.HighPart = (DWORD)(uliDividend.QuadPart / dwDivisor); p[0].HighPart = (DWORD)(uliDividend.QuadPart % dwDivisor); uliResult.LowPart = 0; uliResult.QuadPart = p[0].QuadPart / dwDivisor + uliResult.QuadPart;#else /* NOTE - this routine will take exceptions if the result does not fit in a DWORD */ if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) { uliResult.HighPart = EnlargedUnsignedDivide( uliDividend, dwDivisor, &p[0].HighPart); } else { uliResult.HighPart = 0; } uliResult.LowPart = EnlargedUnsignedDivide( p[0], dwDivisor, NULL);#endif return bSign ? -(LONGLONG)uliResult.QuadPart : (LONGLONG)uliResult.QuadPart; } ullResult = 0; /* OK - do long division */ for (int i = 0; i < 64; i++) { ullResult <<= 1; /* Shift 128 bit p left 1 */ p[1].QuadPart <<= 1; if ((p[0].HighPart & 0x80000000) != 0) { p[1].LowPart++; } p[0].QuadPart <<= 1; /* Compare */ if (uc <= p[1].QuadPart) { p[1].QuadPart -= uc; ullResult += 1; } } return bSign ? - (LONGLONG)ullResult : (LONGLONG)ullResult;}LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG d){ ULARGE_INTEGER ua; DWORD ub; DWORD uc; /* Compute the absolute values to avoid signed arithmetic problems */ ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a); ub = (DWORD)(b >= 0 ? b : -b); uc = (DWORD)(c >= 0 ? c : -c); BOOL bSign = (a < 0) ^ (b < 0); /* Do long multiplication */ ULARGE_INTEGER p0; DWORD p1; p0.QuadPart = UInt32x32To64(ua.LowPart, ub); if (ua.HighPart != 0) { ULARGE_INTEGER x; x.QuadPart = UInt32x32To64(ua.HighPart, ub) + p0.HighPart; p0.HighPart = x.LowPart; p1 = x.HighPart; } else { p1 = 0; } if (d != 0) { ULARGE_INTEGER ud0; DWORD ud1; if (bSign) { // // Cast d to LONGLONG first otherwise -0x80000000 sign extends // incorrectly // ud0.QuadPart = (DWORDLONG)(-(LONGLONG)d); if (d > 0) { /* -d < 0 */ ud1 = (DWORD)-1; } else { ud1 = (DWORD)0; } } else { ud0.QuadPart = (DWORDLONG)d; if (d < 0) { ud1 = (DWORD)-1; } else { ud1 = (DWORD)0; } } /* Now do extended addition */ ULARGE_INTEGER uliTotal; /* Add ls DWORDs */ uliTotal.QuadPart = (DWORDLONG)ud0.LowPart + p0.LowPart; p0.LowPart = uliTotal.LowPart; /* Propagate carry */ uliTotal.LowPart = uliTotal.HighPart; uliTotal.HighPart = 0; /* Add 2nd most ls DWORDs */ uliTotal.QuadPart += (DWORDLONG)ud0.HighPart + p0.HighPart; p0.HighPart = uliTotal.LowPart; /* Add MS DWORDLONGs - no carry expected */ p1 += ud1 + uliTotal.HighPart; /* Now see if we got a sign change from the addition */ if ((LONG)p1 < 0) { bSign = !bSign; /* Negate the current value (ugh!) */ p0.QuadPart = ~p0.QuadPart; p1 = ~p1; p0.QuadPart += 1; p1 += (p0.QuadPart == 0); } } /* Now for the division */ if (c < 0) { bSign = !bSign; } /* This will catch c == 0 and overflow */ if (uc <= p1) { return bSign ? (LONGLONG)0x8000000000000000LL : (LONGLONG)0x7FFFFFFFFFFFFFFFLL; } /* Do the division */ /* If the divisor is a DWORD then its simpler */ ULARGE_INTEGER uliDividend; ULARGE_INTEGER uliResult; DWORD dwDivisor = uc; uliDividend.HighPart = p1; uliDividend.LowPart = p0.HighPart; /* NOTE - this routine will take exceptions if the result does not fit in a DWORD */ if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) { uliResult.HighPart = EnlargedUnsignedDivide( uliDividend, dwDivisor, &p0.HighPart); } else { uliResult.HighPart = 0; } uliResult.LowPart = EnlargedUnsignedDivide( p0, dwDivisor, NULL); return bSign ? -(LONGLONG)uliResult.QuadPart : (LONGLONG)uliResult.QuadPart;}#ifdef DEBUG/******************************Public*Routine******************************\* Debug CCritSec helpers** We provide debug versions of the Constructor, destructor, Lock and Unlock* routines. The debug code tracks who owns each critical section by* maintaining a depth count.** History:*\**************************************************************************/CCritSec::CCritSec(){ InitializeCriticalSection(&m_CritSec); m_currentOwner = m_lockCount = 0; m_fTrace = FALSE;}CCritSec::~CCritSec(){ DeleteCriticalSection(&m_CritSec);}void CCritSec::Lock(){ UINT tracelevel=3; DWORD us = GetCurrentThreadId(); DWORD currentOwner = m_currentOwner; if (currentOwner && (currentOwner != us)) { // already owned, but not by us if (m_fTrace) { DbgLog((LOG_LOCKING, 2, TEXT("Thread %d about to wait for lock %x owned by %d"), GetCurrentThreadId(), &m_CritSec, currentOwner)); tracelevel=2; // if we saw the message about waiting for the critical // section we ensure we see the message when we get the // critical section } } EnterCriticalSection(&m_CritSec); if (0 == m_lockCount++) { // we now own it for the first time. Set owner information m_currentOwner = us; if (m_fTrace) { DbgLog((LOG_LOCKING, tracelevel, TEXT("Thread %d now owns lock %x"), m_currentOwner, &m_CritSec)); } }}void CCritSec::Unlock() { if (0 == --m_lockCount) { // about to be unowned if (m_fTrace) { DbgLog((LOG_LOCKING, 3, TEXT("Thread %d releasing lock %x"), m_currentOwner, &m_CritSec)); } m_currentOwner = 0; } LeaveCriticalSection(&m_CritSec);}void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace){ pcCrit->m_fTrace = fTrace;}BOOL WINAPI CritCheckIn(CCritSec * pcCrit){ return (GetCurrentThreadId() == pcCrit->m_currentOwner);}BOOL WINAPI CritCheckIn(const CCritSec * pcCrit){ return (GetCurrentThreadId() == pcCrit->m_currentOwner);}BOOL WINAPI CritCheckOut(CCritSec * pcCrit){ return (GetCurrentThreadId() != pcCrit->m_currentOwner);}BOOL WINAPI CritCheckOut(const CCritSec * pcCrit){ return (GetCurrentThreadId() != pcCrit->m_currentOwner);}#endifSTDAPI WriteBSTR(BSTR *pstrDest, LPCWSTR szSrc){ *pstrDest = SysAllocString( szSrc ); if( !(*pstrDest) ) return E_OUTOFMEMORY; return NOERROR;}STDAPI FreeBSTR(BSTR* pstr){ if( *pstr == NULL ) return S_FALSE; SysFreeString( *pstr ); return NOERROR;}// Return a wide string - allocating memory for it// Returns:// S_OK - no error// E_POINTER - ppszReturn == NULL// E_OUTOFMEMORY - can't allocate memory for returned stringSTDAPI AMGetWideString(LPCWSTR psz, LPWSTR *ppszReturn){ CheckPointer(ppszReturn, E_POINTER); ValidateReadWritePtr(ppszReturn, sizeof(LPWSTR)); DWORD nameLen = sizeof(WCHAR) * (lstrlenW(psz)+1); *ppszReturn = (LPWSTR)CoTaskMemAlloc(nameLen); if (*ppszReturn == NULL) { return E_OUTOFMEMORY; } CopyMemory(*ppszReturn, psz, nameLen); return NOERROR;}// Waits for the HANDLE hObject. While waiting messages sent// to windows on our thread by SendMessage will be processed.// Using this function to do waits and mutual exclusion// avoids some deadlocks in objects with windows.// Return codes are the same as for WaitForSingleObjectDWORD WINAPI WaitDispatchingMessages( HANDLE hObject, DWORD dwWait, HWND hwnd, UINT uMsg, HANDLE hEvent){ BOOL bPeeked = FALSE; DWORD dwResult; DWORD dwStart; DWORD dwThreadPriority; static UINT uMsgId = 0; HANDLE hObjects[2] = { hObject, hEvent }; if (dwWait != INFINITE && dwWait != 0) { dwStart = GetTickCount(); } for (; ; ) { DWORD nCount = NULL != hEvent ? 2 : 1; // Minimize the chance of actually dispatching any messages // by seeing if we can lock immediately. dwResult = WaitForMultipleObjects(nCount, hObjects, FALSE, 0); if (dwResult < WAIT_OBJECT_0 + nCount) { break; } DWORD dwTimeOut = dwWait; if (dwTimeOut > 10) { dwTimeOut = 10; } dwResult = MsgWaitForMultipleObjects( nCount, hObjects, FALSE, dwTimeOut, hwnd == NULL ? QS_SENDMESSAGE : QS_SENDMESSAGE + QS_POSTMESSAGE); if (dwResult == WAIT_OBJECT_0 + nCount || dwResult == WAIT_TIMEOUT && dwTimeOut != dwWait) { MSG msg; if (hwnd != NULL) { while (PeekMessage(&msg, hwnd, uMsg, uMsg, PM_REMOVE)) { DispatchMessage(&msg); } } // Do this anyway - the previous peek doesn't flush out the // messages PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); if (dwWait != INFINITE && dwWait != 0) { DWORD dwNow = GetTickCount(); // Working with differences handles wrap-around DWORD dwDiff = dwNow - dwStart; if (dwDiff > dwWait) { dwWait = 0; } else { dwWait -= dwDiff; } dwStart = dwNow; } if (!bPeeked) { // Raise our priority to prevent our message queue // building up dwThreadPriority = GetThreadPriority(GetCurrentThread()); if (dwThreadPriority < THREAD_PRIORITY_HIGHEST) { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); } bPeeked = TRUE; } } else { break; } } if (bPeeked) { SetThreadPriority(GetCurrentThread(), dwThreadPriority); if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) { if (uMsgId == 0) { uMsgId = RegisterWindowMessage(TEXT("AMUnblock")); } if (uMsgId != 0) { MSG msg; // Remove old ones while (PeekMessage(&msg, (HWND)-1, uMsgId, uMsgId, PM_REMOVE)) { } } PostThreadMessage(GetCurrentThreadId(), uMsgId, 0, 0); } } return dwResult;}HRESULT AmGetLastErrorToHResult(){ DWORD dwLastError = GetLastError(); if(dwLastError != 0) { return HRESULT_FROM_WIN32(dwLastError); } else { return E_FAIL; }}IUnknown* QzAtlComPtrAssign(IUnknown** pp, IUnknown* lp){ if (lp != NULL) lp->AddRef(); if (*pp) (*pp)->Release(); *pp = lp; return lp;}/******************************************************************************CompatibleTimeSetEvent CompatibleTimeSetEvent() sets the TIME_KILL_SYNCHRONOUS flag before callingtimeSetEvent() if the current operating system supports it. TIME_KILL_SYNCHRONOUSis supported on Windows XP and later operating systems.Parameters:- The same parameters as timeSetEvent(). See timeSetEvent()'s documentation in the Platform SDK for more information.Return Value:- The same return value as timeSetEvent(). See timeSetEvent()'s documentation in the Platform SDK for more information.******************************************************************************/MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent ){ #if WINVER >= 0x0501 { static bool fCheckedVersion = false; static bool fTimeKillSynchronousFlagAvailable = false; if( !fCheckedVersion ) { fTimeKillSynchronousFlagAvailable = TimeKillSynchronousFlagAvailable(); fCheckedVersion = true; } if( fTimeKillSynchronousFlagAvailable ) { fuEvent = fuEvent | TIME_KILL_SYNCHRONOUS; } } #endif // WINVER >= 0x0501 return timeSetEvent( uDelay, uResolution, lpTimeProc, dwUser, fuEvent );}bool TimeKillSynchronousFlagAvailable( void ){ OSVERSIONINFO osverinfo; osverinfo.dwOSVersionInfoSize = sizeof(osverinfo); if( GetVersionEx( &osverinfo ) ) { // Windows XP's major version is 5 and its' minor version is 1. // timeSetEvent() started supporting the TIME_KILL_SYNCHRONOUS flag // in Windows XP. if( (osverinfo.dwMajorVersion > 5) || ( (osverinfo.dwMajorVersion == 5) && (osverinfo.dwMinorVersion >= 1) ) ) { return true; } } return false;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?