⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*
 *	UTIL.C
 *
 *	Purpose:
 *		Implementation of various useful utility functions
 *
 *	Author:
 *		alexgo (4/25/95)
 */

#include "_common.h"
#include "_rtfconv.h"

ASSERTDATA

//Global instance of SystemParams for keeping track of
//certain system wide parameters used in richedit.
CSystemParams sysparam;

// Author revision color table
const COLORREF rgcrRevisions[] =
{
        RGB(0, 0, 255),
        RGB(0, 128, 0),
        RGB(255, 0, 0),
        RGB(0, 128, 128),
        RGB(128, 0, 128),
        RGB(0, 0, 128),
        RGB(128, 0, 0),
        RGB(255, 0, 255)
};

#if REVMASK != 7
#pragma message ("WARNING, Revision mask not equal to table!");
#endif 



/*
 *	DuplicateHGlobal
 *
 *	Purpose:
 *		duplicates the passed in hglobal
 */

HGLOBAL DuplicateHGlobal( HGLOBAL hglobal )
{
	TRACEBEGIN(TRCSUBSYSUTIL, TRCSCOPEINTERN, "DuplicateHGlobal");

	UINT	flags;
	DWORD	size;
	HGLOBAL hNew;
	BYTE *	pSrc;
	BYTE *	pDest;

	if( hglobal == NULL )
	{
		return NULL;
	}

	flags = GlobalFlags(hglobal);
	size = GlobalSize(hglobal);
	hNew = GlobalAlloc(flags, size);

	if( hNew )
	{
		pDest = (BYTE *)GlobalLock(hNew);
		pSrc = (BYTE *)GlobalLock(hglobal);

		if( pDest == NULL || pSrc == NULL )
		{
			GlobalUnlock(hNew);
			GlobalUnlock(hglobal);
			GlobalFree(hNew);

			return NULL;
		}

		memcpy(pDest, pSrc, size);

		GlobalUnlock(hNew);
		GlobalUnlock(hglobal);
	}

	return hNew;
}

/*
 *	CountMatchingBits (*pA, *pB, n)
 *
 *	@mfunc
 *		Count matching bit fields
 *
 *	@comm
 *		This is used to help decide how good the match is between
 *		code page bit fields. Mainly for KB/font switching support.
 *
 *	Author:
 *		Jon Matousek
 */
INT CountMatchingBits(
	const DWORD *pA,	//@parm Array A to be matched
	const DWORD *pB,	//@parm Array B to be matched
	INT			 n)		//@parm # DWORDs to be matched
{
	TRACEBEGIN(TRCSUBSYSUTIL, TRCSCOPEINTERN, "CountMatchingBits");
							//0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
	static INT	bitCount[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
	INT			c = 0;				// Bit count to return
	DWORD		matchBits;			// Next DWORD match

	while(n--)
	{
		//matchBits = ~(*pA++ ^ *pB++);			// 1 and 0's
		matchBits = *pA++ & *pB++;				// 1 only
		for( ; matchBits; matchBits >>= 4)		// Early out
			c += bitCount[matchBits & 15];
#if 0
		c += bitCount [(matchBits >> 0)  & 15];	// No early out
		c += bitCount [(matchBits >> 4)  & 15];
		c += bitCount [(matchBits >> 8)  & 15];
		c += bitCount [(matchBits >> 12) & 15];
		c += bitCount [(matchBits >> 16) & 15];
		c += bitCount [(matchBits >> 20) & 15];
		c += bitCount [(matchBits >> 24) & 15];
		c += bitCount [(matchBits >> 28) & 15];
#endif
#if 0
		for( ; matchBits; c++)					// For random data, has
			matchBits &= matchBits - 1;			//  about 16 passes
#endif
	}
	return c;
}



//FUTURE: (v-richa) If it becomes practical to detect when the various
//system values handled by this class change, we should add a mechanism
//to update them dynamically.
/*
 *	CSystemParams::CSystemParams(void)
 *
 *	@mfunc
 *		This class is used to handle certain system wide parameters that
 *      that are used in richedit.  the constructor just initializes
 *      things to a known state so we can tell whether they have been
 *      previously set.
 *
 */
CSystemParams::CSystemParams(void)
{
	TRACEBEGIN(TRCSUBSYSUTIL, TRCSCOPEINTERN, "SystemParams::SystemParams");
    _nScrollInset = 0;
    _nScrollDelay = 0;
    _nScrollInterval = 0;
	_nScrollVAmount = 0;
	_nScrollHAmount = 0;
	_nDragDelay = 0;
	_hcurSizeNS = NULL;
	_hcurSizeWE = NULL;
	_hcurSizeNWSE = NULL;
	_hcurSizeNESW = NULL;

	_fDirty = TRUE;
}

/*
 *	CSystemParams::~CSystemParams(void)
 *
 *	@mfunc
 *      Destructor.
 *
 */
CSystemParams::~CSystemParams(void)
{
	TRACEBEGIN(TRCSUBSYSUTIL, TRCSCOPEINTERN, "SystemParams::~SystemParams");
}

/*
 *	CSystemParams::GetScrollInset(void)
 *
 *	@mfunc
 *      If value has been set, return it.
 *      Otherwise get the default and then return the value.
 *
 */
WORD CSystemParams::GetScrollInset(void)
{
    if (_nScrollInset)
        return _nScrollInset;

    _nScrollInset =
        (WORD)GetProfileIntA( "windows", "ScrollInset", DD_DEFSCROLLINSET );

    return _nScrollInset;
}

/*
 *	CSystemParams::GetScrollDelay(void)
 *
 *	@mfunc
 *      If value has been set, return it.
 *      Otherwise get the default and then return the value.
 *
 */
WORD CSystemParams::GetScrollDelay(void)
{
    if (_nScrollDelay)
        return _nScrollDelay;

    _nScrollDelay =
        (WORD)GetProfileIntA( "windows", "ScrollDelay", DD_DEFSCROLLDELAY );

    return _nScrollDelay;
}

/*
 *	CSystemParams::GetScrollInterval(void)
 *
 *	@mfunc
 *      If value has been set, return it.
 *      Otherwise get the default and then return the value.
 *
 */
WORD CSystemParams::GetScrollInterval(void)
{
    if (_nScrollInterval)
        return _nScrollInterval;

    _nScrollInterval =
        (WORD)GetProfileIntA( "windows", "ScrollInterval", DD_DEFSCROLLINTERVAL );

    return _nScrollInterval;
}

/*
 *	CSystemParams::GetScrollVAmount(void)
 *
 *	@mfunc
 *      If value has been set, return it.
 *      Otherwise get the default and then return the value.
 *
 */
WORD CSystemParams::GetScrollVAmount(void)
{
    if (_nScrollVAmount)
        return _nScrollVAmount;

    _nScrollVAmount = (GetYPerInchScreenDC()*DEFSCROLLVAMOUNT)/100;

    return _nScrollVAmount;
}

/*
 *	CSystemParams::GetScrollHAmount(void)
 *
 *	@mfunc
 *      If value has been set, return it.
 *      Otherwise get the default and then return the value.
 *
 */
WORD CSystemParams::GetScrollHAmount(void)
{
    if (_nScrollHAmount)
        return _nScrollHAmount;

    _nScrollHAmount = (GetXPerInchScreenDC()*DEFSCROLLHAMOUNT)/100;

    return _nScrollHAmount;
}

/*
 *	CSystemParams::GetDragDelay(void)
 *
 *	@mfunc
 *      If value has been set, return it.
 *      Otherwise get the default and then return the value.
 *
 */
WORD CSystemParams::GetDragDelay(void)
{
    if (_nDragDelay)
        return _nDragDelay;

    _nDragDelay =
        (WORD)GetProfileIntA( "windows", "DragDelay", DD_DEFDRAGDELAY );

    return _nDragDelay;
}

/*
 *	CSystemParams::GetDragMinDist(void)
 *
 *	@mfunc
 *      If value has been set, return it.
 *      Otherwise get the default and then return the value.
 *
 */
WORD CSystemParams::GetDragMinDist(void)
{
    if (_nDragMinDist)
        return _nDragMinDist;

    _nDragMinDist =
        (WORD)GetProfileIntA( "windows", "DragMinDist", DD_DEFDRAGMINDIST );

    return _nDragMinDist;
}

/*
 *	CSystemParams::GetSizeCursor(void)
 *
 *	@mfunc
 *		Get the sizing cursor (double arrow) specified by
 *		the resource id.  If the cursors are not loaded
 *		load them and cache them.
 *		parameters:
 *			idcur - cursor resource id.
 *
 *	@rdesc
 *		Handle to cursor or null if failure. Returns NULL if
 *		idcur is null.
 */
HCURSOR CSystemParams::GetSizeCursor(LPTSTR idcur)
{
	if( !idcur )
	{
		return NULL;
	}

	//If any of the cursors aren't loaded, try loading them.
	if( !(_hcurSizeNS && _hcurSizeWE && _hcurSizeNWSE && _hcurSizeNESW) )
	{
		if (!_hcurSizeNS)
		{
			_hcurSizeNS = LoadCursor(NULL, IDC_SIZENS);
		}
		if (!_hcurSizeWE)
		{
			_hcurSizeWE = LoadCursor(NULL, IDC_SIZEWE);
		}
		if (!_hcurSizeNWSE)
		{
			_hcurSizeNWSE = LoadCursor(NULL, IDC_SIZENWSE);
		}
		if (!_hcurSizeNESW)
		{
			_hcurSizeNESW = LoadCursor(NULL, IDC_SIZENESW);
		}
	}
	
	//Return the cursor corresponding to the id passed in.
	if( (idcur == IDC_SIZENS) && _hcurSizeNS)
	{
		return _hcurSizeNS;
	}
	if( (idcur == IDC_SIZEWE) && _hcurSizeWE )
	{
		return _hcurSizeWE;
	}
	if( (idcur == IDC_SIZENWSE) && _hcurSizeNWSE )
	{
		return _hcurSizeNWSE;
	}
	if( (idcur == IDC_SIZENESW) && _hcurSizeNESW )
	{
		return _hcurSizeNESW;
	}

	AssertSz(FALSE, "Failure loading sizing cursor.");

	return NULL;
}

/* excerpt from new winuser.h for calls to SystemParametersInfo */
#ifndef SPI_GETWHEELSCROLLLINES
#define SPI_GETWHEELSCROLLLINES   104
#endif

/*
 *	CSystemParams::GetRollerLineScrollCount()
 *
 *	@mfunc	returns the number of lines to scroll with a roller mouse wheel.
 *			-1 means scroll by pages
 *
 *	@devnote We have to do different things for different platforms; NT4.0 has
 *			built in support for this functionality.
 */

LONG CSystemParams::GetRollerLineScrollCount()
{
#ifndef PEGASUS
	if( _cLineScroll == 0 )
	{
		// this stuff isn't supported on the MAC
#ifndef _MAC
		HKEY hdlKey;
		DWORD keyDataType;
		CHAR charData[128];
		DWORD  dwDataBufSize;

		// Read registry directly for Windows 9x & WinNT3.51, if WinNT 4.0 
		// and above then use SystemParametersInfo

		if( (dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) ||
				(dwPlatformId == VER_PLATFORM_WIN32_NT) && 
				(dwMajorVersion < 4))
		{
			// Read registry directly
			if ( RegOpenKeyExA(HKEY_CURRENT_USER, 
						"Control Panel\\Desktop", 
						0,
						KEY_QUERY_VALUE,
						&hdlKey) == ERROR_SUCCESS )
			{
				dwDataBufSize = sizeof(charData);
				if ( RegQueryValueExA(hdlKey, 
							  "WheelScrollLines",
							  NULL,  // reserved
							  &keyDataType,
							  (LPBYTE) &charData,
							  &dwDataBufSize) == ERROR_SUCCESS )
				{
					_cLineScroll = strtoul( charData,   //String representation
                     			  NULL,
                    			  10);
				}
			}
			RegCloseKey(hdlKey); 
		}   
		else if ( (dwPlatformId == VER_PLATFORM_WIN32_NT) &&
             (dwMajorVersion >= 4) )
		{
			SystemParametersInfoA(SPI_GETWHEELSCROLLLINES, 0, &_cLineScroll, 0);
		}

#endif // _MAC
		// if we still didn't get anything good, fall back to the default
		if( _cLineScroll == 0 )
		{
			_cLineScroll = 3;
		}
	}

#endif

	return _cLineScroll;
}


//
//	Object Stabilization classes
//

//+-------------------------------------------------------------------------
//
//  Member:		CSafeRefCount::CSafeRefCount
//
//  Synopsis: 	constructor for the safe ref count class
//
//  Effects:
//
//  Arguments:	none
//
//  Requires: 	
//
//  Returns: 	none
//
//  Signals:
//
//  Modifies:
//
//  Derivation:
//
//  Algorithm:
//
//  History:    dd-mmm-yy Author    Comment
// 				28-Jul-94 alexgo    author
//
//  Notes:
//
//--------------------------------------------------------------------------

CSafeRefCount::CSafeRefCount()
{
	m_cRefs = 0;
	m_cNest = 0;
	m_fInDelete = FALSE;
    m_fForceZombie = FALSE;
}

//+-------------------------------------------------------------------------
//
//  Member: 	CSafeRefCount::CSafeRefCount (virtual)
//
//  Synopsis:	
//
//  Effects:
//
//  Arguments:
//
//  Requires:
//
//  Returns:
//
//  Signals:
//
//  Modifies:
//
//  Derivation:
//
//  Algorithm:
//
//  History:    dd-mmm-yy Author    Comment
// 				28-Jul-94 alexgo    author
//
//  Notes:
//
//--------------------------------------------------------------------------

CSafeRefCount::~CSafeRefCount()
{
	Assert(m_cRefs == 0 && m_cNest == 0 && m_fInDelete == TRUE);
}

//+-------------------------------------------------------------------------
//
//  Member: 	CSafeRefCount::SafeAddRef
//
//  Synopsis:	increments the reference count on the object
//
//  Effects:
//
//  Arguments: 	none
//
//  Requires:
//
//  Returns: 	ULONG -- the reference count after the increment
//
//  Signals:
//
//  Modifies:
//
//  Derivation:
//
//  Algorithm:	increments the reference count.
//
//  History:    dd-mmm-yy Author    Comment
//   			28-Jul-94 alexgo    author
//
//  Notes:
//
//--------------------------------------------------------------------------

ULONG CSafeRefCount::SafeAddRef()
{
	m_cRefs++;

	//AssertSz(m_fInDelete == FALSE, "AddRef called on deleted object!");

	// this *could* be really bad.  If we are deleting the object,
	// it means that during the destructor, somebody made an outgoing
	// call eventually ended up with another addref to ourselves
	// (even though	all pointers to us had been 'Released').
	//
	// this is usually caused by code like the following:
	//	m_pFoo->Release();
	//	m_pFoo = NULL;
	//
	// If the the Release may cause Foo to be deleted, which may cause
	// the object to get re-entered during Foo's destructor.  However,
	// 'this' object has not yet set m_pFoo to NULL, so it may
	// try to continue to use m_pFoo.
	//
	// However, the May '94 aggregation rules REQUIRE this behaviour
	// In your destructor, you have to addref the outer unknown before

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -