📄 wxutil.cpp
字号:
#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)0x8000000000000000 :
(LONGLONG)0x7FFFFFFFFFFFFFFF;
}
/* 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;
//ASSERT(((PRTL_CRITICAL_SECTION)&m_CritSec)->OwningThread == (HANDLE)m_currentOwner);
// only valid on NT
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));
//ASSERT(((PRTL_CRITICAL_SECTION)&m_CritSec)->OwningThread == (HANDLE)m_currentOwner);
// only valid on NT
}
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 CritCheckOut(CCritSec * pcCrit)
{
return (GetCurrentThreadId() != pcCrit->m_currentOwner);
}
#endif
typedef void (STDAPICALLTYPE *LPSYSFREESTRING)(BSTR);
typedef BSTR (STDAPICALLTYPE *LPSYSALLOCSTRING)(const OLECHAR FAR *);
static HINSTANCE hOleAut32 = NULL;
static LPSYSALLOCSTRING lpfnSysAllocString = NULL;
static LPSYSFREESTRING lpfnSysFreeString = NULL;
STDAPI LoadOleAut32( void )
{
HRESULT hr = S_OK;
if( hOleAut32 == NULL )
{
hOleAut32 = LoadOLEAut32();
if( hOleAut32 )
{
lpfnSysAllocString = (LPSYSALLOCSTRING)GetProcAddress( hOleAut32, L"SysAllocString" );
lpfnSysFreeString = (LPSYSFREESTRING)GetProcAddress( hOleAut32, L"SysFreeString" );
if( !lpfnSysAllocString || !lpfnSysFreeString )
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
return hr;
}
// Dyna-link to SysAllocString to copy BSTR strings
STDAPI WriteBSTR(BSTR *pstrDest, LPCWSTR szSrc)
{
HRESULT hr = LoadOleAut32();
if( SUCCEEDED( hr ) )
*pstrDest = (*lpfnSysAllocString)(szSrc);
return hr;
}
// Free an OLE BSTR through the task allocator
STDAPI FreeBSTR(BSTR* pstr)
{
if (*pstr != NULL) {
if( SUCCEEDED( LoadOleAut32() ) )
{
(*lpfnSysFreeString)(*pstr);
*pstr = NULL;
}
return S_OK;
} else {
return S_FALSE;
}
}
// 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 string
STDAPI 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 WaitForSingleObject
DWORD WINAPI WaitDispatchingMessages(HANDLE hObject, DWORD dwWait, HWND hwnd, UINT uMsg)
{
BOOL bPeeked = FALSE;
DWORD dwResult;
DWORD dwStart;
DWORD dwThreadPriority;
if (dwWait != INFINITE && dwWait != 0) {
dwStart = timeGetTime();
}
for (; ; ) {
DWORD dwTimeOut = dwWait;
if (dwTimeOut > 10) {
dwTimeOut = 10;
}
dwResult = MsgWaitForMultipleObjects(
1,
&hObject,
FALSE,
dwTimeOut,
hwnd == NULL ? QS_SENDMESSAGE : QS_SENDMESSAGE + QS_POSTMESSAGE);
if (dwResult == WAIT_OBJECT_0 + 1 ||
dwResult == WAIT_TIMEOUT && dwTimeOut != dwWait &&
dwWait > 0) // BUGBUG: Don't dispatch messages if wait is zero.
{
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 = timeGetTime();
// Working with differences handles wrap-around
DWORD dwDiff = dwNow - dwStart;
if (dwDiff > dwWait) {
dwWait = 0;
dwResult = WAIT_TIMEOUT;
break;
} else {
dwWait -= dwDiff;
}
dwStart = dwNow;
}
if (!bPeeked)
{
// Raise our priority to prevent our message queue
// building up
dwThreadPriority = _internal_GetThreadPriority(GetCurrentThread());
if (dwThreadPriority < THREAD_PRIORITY_HIGHEST) {
_internal_SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
}
bPeeked = TRUE;
}
} else {
break;
}
}
if (bPeeked) {
_internal_SetThreadPriority(GetCurrentThread(), dwThreadPriority);
#ifndef UNDER_CE
if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) {
// Send dummy message
PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
}
#endif // UNDER_CE
}
return dwResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -