gusucode.com > 如何截取QQ密码和聊天内容、去掉QQ广告栏、添加QQ尾巴 > 如何截取QQ密码和聊天内容、去掉QQ广告栏、添加QQ尾巴/RemoteThreadMateQQ/dllRemoteThread/CommonFunc.cpp

    // CommonFunc.cpp: implementation of the CCommonFunc class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CommonFunc.h"
#include "QQMate.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

extern HWND g_hWnd_Invoker;
extern CString g_csCurModuleBaseName;


const TCHAR *f_WeekStr[] = 
{
	_T(""), _T("Sun."), _T("Mon."), _T("Tue."), _T("Wed."), _T("Thu."), _T("Fri."), _T("Sta."), _T(""),
};

const TCHAR *f_PAM[] = 
{
	_T("A.M."), _T("P.M."), _T(""),
};


DWORD GetCurTimeString(char *buf)
{
	struct tm *tt;
	time_t now = time(NULL);
	tt = localtime(&now);
	return (DWORD)strftime(buf, 22, "%y-%m-%d %H:%M:%S", tt);
}

time_t GetCurrentTimeHw ()
{
	SYSTEMTIME stm;
	GetLocalTime ( &stm );
	CTime tNow ( stm );
	return (time_t)tNow.GetTime ();
}

int WriteDataToFile(LPCTSTR filename,PUCHAR data,long size,LPCTSTR mode)
{
	FILE *fp;
	long retval;
	fp=fopen((const char*)filename,(const char*)mode);
	if ( fp!=NULL)
	{
		retval = (long)fwrite(data,sizeof(UCHAR),size,fp);
		fclose(fp);
		if(retval != size)
		{
			return -1;
		}
		else 	return retval;
	}
	else
	{
		return -1;
	}
}

/********************************************************************************
* Function Type	:	public
* Parameter		:	bMsgBox		-	是否输出到对话框
*					format		-	格式化字符串
* Return Value	:	None
* Description	:	输出日志信息
*********************************************************************************/
void Log ( int nLevel, LPCTSTR format, ...)
{
	// 格式化日志信息
	DWORD len = 0;
	char LogBuf[1024] = {0};
	len += _snprintf ( &LogBuf[len], sizeof(LogBuf) - len - 2,
		"【" );
	len += GetCurTimeString( &LogBuf[len] );
	len += _snprintf ( &LogBuf[len], sizeof(LogBuf) - len - 2,
		"】: (PID:%u) %s : ", GetCurrentProcessId(), g_csCurModuleBaseName );
	va_list  va;
	va_start (va, format);
	len += _vsnprintf ((char*)&LogBuf[len],sizeof(LogBuf) - len - 3, (const char*)format, va);
	va_end(va);
	strcat( LogBuf, "\r\n" );
	len += 2;
#ifdef _DEBUG
	if ( nLevel & L_TRACE )
	{
		TRACE ( LogBuf );
	}
#endif
	if ( nLevel & L_OUT_DLG )
	{
		AfxMessageBox ( LogBuf );
	}
	// 保存日志信息
	WriteDataToFile( (LPCTSTR)"c:\\RemoteThreadMateQQ.txt", (PUCHAR)LogBuf, len, "ab+" );
	if ( !(L_ONLY_LOGFILE & nLevel) )
		SendMessageIV ( RMSG_LOG, 0, LogBuf );
}

int hwGetModuleBaseName(LPSTR lpBuf,DWORD dwSize)
{
	ZeroMemory ( lpBuf, dwSize );
	char TempBuf[MAX_PATH] = {0};
	int nLen = GetModuleFileName ( NULL,(LPTSTR)TempBuf, sizeof(TempBuf) );
	char *p = strrchr((const char*)TempBuf,'\\');
	if ( !p ) return 0;
	if ( p - TempBuf >= nLen-1 ) return 0;
	strncpy ( lpBuf, p+1, dwSize );
	return ( nLen - (p-TempBuf) -1 );
}

CString hwGetModuleBaseName()
{
	char szTemp[MAX_PATH] = {0};
	hwGetModuleBaseName ( szTemp, sizeof(szTemp) );
	return szTemp;
}

/********************************************************************************
* Function Type	:	Global
* Parameter		:	lpProgram	-	存放当前执行程序所在的路径字符串的缓冲
*					dwSize		-	缓冲大小
* Return Value	:	字符个数
* Description	:	得到当前执行程序所在的路径
*********************************************************************************/
int GetProgramDir ( LPTSTR lpProgram, DWORD dwSize )
{
	ASSERT ( lpProgram );
	ZeroMemory(lpProgram,dwSize);
	GetModuleFileName(NULL,(LPTSTR)lpProgram,dwSize);
	LPTSTR p = (LPTSTR)strrchr_hw((LPCTSTR)lpProgram, _T('\\'));
	if(!p) return 0;
	p[1] = _T('\0');
	int nLength = (int)(p - lpProgram)/sizeof(TCHAR);
	
	return nLength;
}

CString GetProgramDir()
{
	TCHAR szProgram[MAX_PATH] = {0};
	GetProgramDir ( szProgram, sizeof(szProgram) );
	return szProgram;
}

//
// 从字符串 lpszOrg 中找 cFind 系列字符任何一个字符出现的位置,能防止中文后半部分被误找的情况发生
// 注意:cFind 输入应该以'\0'作为结束标志
// ret : ------------------------------------------------------------------
//		>= nStart	-	找到的位置
//		-1			-	没找
//
int StrFind ( LPCTSTR lpszOrg, int nStart, TCHAR cFind, ... )
{
	if ( !lpszOrg || nStart < 0 ) return -1;
	CUIntArray UIntAryFind;
	
	// 取得所有的 cFind 输入添加到数组中
	va_list list;
	va_start( list, cFind );
	while ( cFind != _T('\0') )
	{
		UIntAryFind.Add ( cFind );
		cFind = va_arg( list, TCHAR );
	}
	va_end( list );
	
	int nChineseCharCount = 0;
	BOOL bChineseStart = FALSE;
	int nFoundPos = -1;
	for ( int i=nStart; lpszOrg[i] != _T('\0'); i++ )
	{
		TCHAR chCur = lpszOrg[i];
		if ( chCur < 0 )
		{
			nChineseCharCount ++;
			bChineseStart = TRUE;
		}
		else
		{
			if ( (nChineseCharCount % 2) == 1 )
				nChineseCharCount ++;
			else
				bChineseStart = FALSE;
		}
		
		if	(
			!bChineseStart
			&&
			FindFromArray ( UIntAryFind, chCur ) >= 0
			)
		{
			nFoundPos = i;
			break;
		}
	}
	
	return nFoundPos;
}

//
// 使用 strtok() 函数将字符串分开并添加到字符串数组中,如将字符串“aaa\nbbb\nccc”分开为:
// “aaa”、“bbb”、“ccc”添加到 StrAry 中
//
int PartStringAndAddToStrAry ( LPCTSTR pStr, OUT CStringArray &StrAry, LPCTSTR seps )
{
	if ( !pStr || !seps || lstrlen(seps) < 1 ) return 0;
	int nStrLen = lstrlen(pStr);
	if ( nStrLen < 1 ) return 0;
	TCHAR *pNewStr = new TCHAR[nStrLen+1];
	if ( !pNewStr ) return 0;
	memset ( pNewStr, 0, sizeof(TCHAR)*(nStrLen+1));
	memcpy ( pNewStr, pStr, sizeof(TCHAR)*nStrLen );

	StrAry.RemoveAll();
	TCHAR *token = strtok_hw( pNewStr, seps );
	while( token != NULL )
	{
		/* While there are tokens in "string" */
		StrAry.Add ( token );
		/* Get next token: */
		token = strtok_hw( NULL, seps );
	}
	delete[] pNewStr; pNewStr = NULL;
	return (int)StrAry.GetSize();
}

//
// 将字符串分开并添加到字符串数组中,如将字符串“aaa__098__bbb__098__ccc”分开为:
// “aaa”、“bbb”、“ccc”添加到 StrAry 中,其中 ( 为分隔字符串“__098__”)
//
int PartStringAndAddToStrAry ( LPCTSTR pStr, LPCTSTR lpszPartFlag, OUT CStringArray &StrAry )
{
	StrAry.RemoveAll ();
	if ( !pStr || !lpszPartFlag ) return 0;
	int nFlagLen = lstrlen(lpszPartFlag);
	if ( nFlagLen < 1 ) return 0;
	
	CString csOrg = pStr;
	int nLeftPos = 0;
	int nRightPos = csOrg.Find ( lpszPartFlag, nLeftPos );
	while ( nLeftPos >= 0 && nLeftPos <= nRightPos )
	{
		CString csUnit = csOrg.Mid ( nLeftPos, nRightPos-nLeftPos );
		StrAry.Add ( csUnit );
		nLeftPos = nRightPos + nFlagLen;
		nRightPos = csOrg.Find ( lpszPartFlag, nLeftPos );
	}

	int nOrgLength = csOrg.GetLength();
	if ( nLeftPos < nOrgLength )
	{
		CString csUnit = csOrg.Mid ( nLeftPos, nOrgLength-nLeftPos );
		StrAry.Add ( csUnit );
	}

	return (int)StrAry.GetSize();
}

//
// 将字符串分开并添加到字符串数组中,如将字符串“aaa\nbbb\nccc”分开为:
// “aaa”、“bbb”、“ccc”添加到 StrAry 中,分离标志为 nPartFlag
//
int PartStringAndAddToStrAry ( LPCTSTR pStr, OUT CStringArray &StrAry, TCHAR nPartFlag )
{
	TCHAR *pStart = (TCHAR *)pStr;
	TCHAR *pFind = NULL;
	TCHAR szTempBuf[10240] = {0};
	while ( pFind = strchr_hw ( pStart, nPartFlag ) )
	{
		int nLenBytes = (int)((reinterpret_cast<char*>(pFind)) - (reinterpret_cast<char*>(pStart)));
		if ( nLenBytes > 0 )
		{
			if ( nLenBytes > sizeof(szTempBuf)-2*sizeof(TCHAR) )
				nLenBytes = sizeof(szTempBuf)-2*sizeof(TCHAR);
			memcpy ( szTempBuf, pStart, nLenBytes );
			szTempBuf [ nLenBytes/sizeof(TCHAR) ] = _T('\0');
			CString csTempStr = szTempBuf;
			StrAry.Add ( csTempStr );
		}
		else
		{
			StrAry.Add ( _T("") );
		}

		pStart = pFind + 1;
	}
	if ( (int)( pStart - pStr ) < (int)lstrlen ( pStr ) )
		StrAry.Add ( pStart );

	return (int)StrAry.GetSize();
}

//
// 将字符串分开并添加到字符串数组中,如将字符串“[aaa], [nbbb], [ccc]”分开为:
// “aaa”、“bbb”、“ccc”添加到 StrAry 中,分离标志为 nFirstFlag='[', nSecondFlag=']'
//
int PartStringAndAddToStrAry ( LPCTSTR lpszStr, OUT CStringArray &StrAry, TCHAR nFirstFlag, TCHAR nSecondFlag )
{
	StrAry.RemoveAll();
	int nStartPos = 0, nEndPos = 0;
	CString csBigString = GET_SAFE_STRING ( lpszStr );
	BOOL bSentence = FALSE;
	for ( ;; )
	{
		TCHAR cFindChar = ( bSentence ? nSecondFlag : nFirstFlag );
		int nFindPos = StrFind ( csBigString, nEndPos, cFindChar, _T('\0') );
		if ( nFindPos < 0 )
		{
			if ( bSentence )
			{
				CString csTemp = csBigString.Mid ( nStartPos+1 );
				if ( csTemp.GetLength() > 0 )
					StrAry.Add ( csTemp );
			}
			break;
		}
		if ( !bSentence )
		{
			nStartPos = nFindPos;
			bSentence = TRUE;
		}
		else
		{
			nEndPos = nFindPos;
			CString csTemp = csBigString.Mid ( nStartPos+1, nEndPos-nStartPos-1 );
			StrAry.Add ( csTemp );
			bSentence = FALSE;
		}
		nEndPos = nFindPos + 1;
	}

	return (int)StrAry.GetSize();
}

//
// 将字符串按照不可显示的字符将可显示的字符串分开并添加到字符串数组中,如将字符串“ aaa bbb \t ccc ”分开为:
// “aaa”、“bbb”、“ccc”添加到 StrAry 中
//
int PartStringAndAddToStrAry ( LPCTSTR pStr, OUT CStringArray &StrAry )
{
	if ( !pStr ) return 0;
	StrAry.RemoveAll();
	CString csOrgStr = pStr;
	int nCurPos = 0;
	while ( nCurPos < csOrgStr.GetLength() )
	{
		int nGraphPos = ::FindGraphPos ( csOrgStr, nCurPos );
		if ( nGraphPos < 0 ) break;
		int nNonGraphPos = ::FindNonGraphPos ( csOrgStr, nGraphPos );
		if ( nNonGraphPos < 0 ) nNonGraphPos = csOrgStr.GetLength();
		if ( nGraphPos >= nNonGraphPos ) break;
		CString csCell = csOrgStr.Mid ( nGraphPos, nNonGraphPos-nGraphPos );
		ASSERT ( !csCell.IsEmpty() );
		StrAry.Add ( csCell );
		nCurPos = nNonGraphPos;
	}

	return (int)StrAry.GetSize();
}

//
// 查找可显示的字符位置,空格应该算做不可显示的
//
int FindGraphPos ( CString &csOrg, int nStartPos )
{
	for ( int i=nStartPos; i<csOrg.GetLength(); i++ )
	{
		if ( isgraph_hw(csOrg[i]) )
			return i;
	}
	return -1;
}

//
// 查找不可显示的字符位置,空格应该算做不可显示的
//
int FindNonGraphPos ( CString &csOrg, int nStartPos )
{
	for ( int i=nStartPos; i<csOrg.GetLength(); i++ )
	{
		if ( !isgraph_hw(csOrg[i]) )
			return i;
	}
	return -1;
}

BOOL CopyTextToClipboard ( LPCTSTR lpszText )
{
	if ( !lpszText ) return TRUE;
	int nStrLen = lstrlen(lpszText);
	if ( nStrLen < 1 ) return TRUE;
	CMultiByteString cbsText(lpszText);
	
	if ( !OpenClipboard(NULL) )						// 打开剪切板
		return FALSE;
	
	EmptyClipboard ();
	HANDLE hclip = GlobalAlloc ( GMEM_MOVEABLE, sizeof(char)*(cbsText.GetLength()+1) );	// 在堆上分配缓冲
	char *buf = (char*)GlobalLock(hclip);	// 对内存块加锁,并返回它的内存地址
	strcpy ( buf, cbsText.GetBuffer() );	// 将字符拷贝到内存中
	GlobalUnlock ( hclip );					// 解锁
	SetClipboardData ( CF_TEXT, hclip );	// 向剪切板上放置内存中的数据
	CloseClipboard();						// 关闭剪切板

	return TRUE;
}

CString GetClipBoardText ()
{
	// 判断剪贴板的数据格式是否可以处理。
	if ( !IsClipboardFormatAvailable(CF_TEXT) ) 
	{
		return _T(""); 
	}    

	// 打开剪贴板。
	if ( !OpenClipboard(NULL) )
	{
		return _T(""); 
	}

	CString csText;
	// 获取数据
	HGLOBAL hMem = GetClipboardData(CF_TEXT); 
	if ( hMem )
	{ 
		// 获取字符串
		LPCTSTR lpStr = (LPCTSTR)GlobalLock(hMem); 
		if (lpStr != NULL) 
		{
			csText = GetCompatibleString ( (LPVOID)lpStr, FALSE );
			GlobalUnlock(hMem);
		} 
	} 
	
	EmptyClipboard ();
	//关闭剪贴板。
	CloseClipboard();
	return csText;
}



CMultiByteString::CMultiByteString()
{
	m_pszData = NULL;
	m_nDataSize = 0;
	m_nCharactersNumber = 0;
	m_bNewBuffer = FALSE;
}

//
// 将字符串 lpszOrg 转换为多字节的字符串,如果还要使用多字符串的长度,可以用以下方式来使用这个类:
// CMultiByteString MultiByteString(_T("UNICODE字符串"));
// printf ( "ANSI 字符串为: %s, 字符个数为: %d , 长度为: %d字节\n", MultiByteString.GetBuffer(), MultiByteString.GetLength(), MultiByteString.GetSize() );
//
CMultiByteString::CMultiByteString( LPCTSTR lpszOrg, int nOrgStringEncodeType/*=STRING_IS_SOFTCODE*/, OUT char *pOutBuf/*=NULL*/, int nOutBufSize/*=0*/ )
{
	Set ( lpszOrg, nOrgStringEncodeType, pOutBuf, nOutBufSize );
}

void CMultiByteString::Set( LPCTSTR lpszOrg, int nOrgStringEncodeType/*=STRING_IS_SOFTCODE*/, OUT char *pOutBuf/*=NULL*/, int nOutBufSize/*=0*/ )
{
	m_bNewBuffer = FALSE;
	m_pszData = NULL;
	m_nDataSize = 0;
	m_nCharactersNumber = 0;
	if ( !lpszOrg ) return;

	// 判断原始字符串的编码方式
	BOOL bOrgIsUnicode = FALSE;
	if ( nOrgStringEncodeType == STRING_IS_MULTICHARS ) bOrgIsUnicode = FALSE;
	else if ( nOrgStringEncodeType == STRING_IS_UNICODE ) bOrgIsUnicode = TRUE;
	else
	{
#ifdef UNICODE
		bOrgIsUnicode = TRUE;
#else
		bOrgIsUnicode = FALSE;
#endif
	}

	// 计算字符串个数和需要的目标缓冲大小
	if ( bOrgIsUnicode )
	{
		m_nCharactersNumber = (int)wcslen((WCHAR*)lpszOrg);
		m_nDataSize = (m_nCharactersNumber + 1) * sizeof(WCHAR);
	}
	else
	{
		m_nCharactersNumber = (int)strlen((char*)lpszOrg);
		m_nDataSize = (m_nCharactersNumber + 1) * sizeof(char);
	}

	// 使用调用者传入的缓冲
	if ( pOutBuf && nOutBufSize > 0 )
	{
		m_pszData = pOutBuf;
		m_nDataSize = nOutBufSize;
	}
	// 自己申请内存缓冲
	else
	{
		m_pszData = (char*)new BYTE[m_nDataSize];
		if ( !m_pszData )
		{
			::AfxThrowMemoryException ();
			return;
		}
		m_bNewBuffer = TRUE;
	}
	memset ( m_pszData, 0, m_nDataSize );

	if ( bOrgIsUnicode )
	{
		m_nCharactersNumber = WideCharToMultiByte ( CP_ACP, 0, (LPCWSTR)lpszOrg, m_nCharactersNumber, (LPSTR)m_pszData, m_nDataSize/sizeof(char)-1, NULL, NULL );
		if ( m_nCharactersNumber < 1 ) m_nCharactersNumber = (int)strlen ( m_pszData );
	}
	else
	{
		m_nCharactersNumber = __min ( m_nCharactersNumber, (int)(m_nDataSize/sizeof(char)-1) );
		strncpy ( m_pszData, (const char*)lpszOrg, m_nCharactersNumber );
		m_nCharactersNumber = (int)strlen ( m_pszData );
	}
	m_nDataSize = ( m_nCharactersNumber + 1 ) * sizeof(char);
}

CMultiByteString::~CMultiByteString ()
{
	if ( m_bNewBuffer && m_pszData )
	{
		delete[] m_pszData;
	}
}

CWideCharString::CWideCharString()
{
	m_pszData = NULL;
	m_nDataSize = 0;
	m_nCharactersNumber = 0;
	m_bNewBuffer = FALSE;
}

//
// 将字符串 lpszOrg 转换为宽字节的字符串,如果还要使用宽字符串的长度或字节尺寸,可以用以下方式来使用这个类:
// CWideCharString WideCharString(_T("ANSI字符串"));
// printf ( "UNICODE 字符串为: %s, 长度为: %d 个字符,字节大小:%d 个字节\n", WideCharString.GetBuffer(), WideCharString.GetLength(), WideCharString.GetSize() );
//
CWideCharString::CWideCharString( LPCTSTR lpszOrg, int nOrgStringEncodeType/*=STRING_IS_SOFTCODE*/, OUT WCHAR *pOutBuf/*=NULL*/, int nOutBufSize/*=0*/ )
{
	Set ( lpszOrg, nOrgStringEncodeType, pOutBuf, nOutBufSize );
}

void CWideCharString::Set( LPCTSTR lpszOrg, int nOrgStringEncodeType/*=STRING_IS_SOFTCODE*/, OUT WCHAR *pOutBuf/*=NULL*/, int nOutBufSize/*=0*/ )
{
	m_bNewBuffer = FALSE;
	m_pszData = NULL;
	m_nDataSize = 0;
	m_nCharactersNumber = 0;
	if ( !lpszOrg ) return;

	// 判断原始字符串的编码方式
	BOOL bOrgIsUnicode = FALSE;
	if ( nOrgStringEncodeType == STRING_IS_MULTICHARS ) bOrgIsUnicode = FALSE;
	else if ( nOrgStringEncodeType == STRING_IS_UNICODE ) bOrgIsUnicode = TRUE;
	else
	{
#ifdef UNICODE
		bOrgIsUnicode = TRUE;
#else
		bOrgIsUnicode = FALSE;
#endif
	}

	// 计算字符串个数和需要的目标缓冲大小
	if ( bOrgIsUnicode )
	{
		m_nCharactersNumber = (int)wcslen((WCHAR*)lpszOrg);
		m_nDataSize = (m_nCharactersNumber + 1) * sizeof(WCHAR);
	}
	else
	{
		m_nCharactersNumber = (int)strlen((char*)lpszOrg);
		m_nDataSize = (m_nCharactersNumber + 1) * sizeof(WCHAR);
	}

	// 使用调用者传入的缓冲
	if ( pOutBuf && nOutBufSize > 0 )
	{
		m_pszData = pOutBuf;
		m_nDataSize = nOutBufSize;
	}
	// 自己申请内存缓冲
	else
	{
		m_pszData = (WCHAR*)new BYTE[m_nDataSize];
		if ( !m_pszData )
		{
			::AfxThrowMemoryException ();
			return;
		}
		m_bNewBuffer = TRUE;
	}
	memset ( m_pszData, 0, m_nDataSize );

	if ( !bOrgIsUnicode )
	{
		m_nCharactersNumber = MultiByteToWideChar ( CP_ACP, 0, (LPCSTR)lpszOrg, m_nCharactersNumber, (LPWSTR)m_pszData, m_nDataSize/sizeof(WCHAR)-1 );
		if ( m_nCharactersNumber < 1 ) m_nCharactersNumber = (int)wcslen ( m_pszData );
	}
	else
	{
		m_nCharactersNumber = __min ( m_nCharactersNumber, (int)(m_nDataSize/sizeof(WCHAR)-1) );
		wcsncpy ( m_pszData, (LPWSTR)lpszOrg, m_nCharactersNumber );
		m_nCharactersNumber = (int)wcslen ( m_pszData );
	}
	m_nDataSize = ( m_nCharactersNumber + 1 ) * sizeof(WCHAR);
}

CWideCharString::~CWideCharString ()
{
	if ( m_bNewBuffer && m_pszData )
	{
		delete[] m_pszData;
	}
}

//
// 将 lpszOrg 转换为该程序使用的编码字符串,如果该程序是 UNICODE 就转为 UNICODE,如果是 ANSI 就转为 ANSI 的
//
CString GetCompatibleString ( LPVOID lpszOrg, BOOL bOrgIsUnicode, int nOrgLength/*=-1*/ )
{
	if ( !lpszOrg ) return _T("");

	TRY
	{
#ifdef UNICODE
		if ( bOrgIsUnicode )
		{
			if ( nOrgLength > 0 )
			{
				WCHAR *szRet = new WCHAR[nOrgLength+1];
				if ( !szRet ) return _T("");
				memset ( szRet, 0, (nOrgLength+1)*sizeof(WCHAR) );
				memcpy ( szRet, lpszOrg, nOrgLength*sizeof(WCHAR) );
				CString csRet = szRet;
				delete[] szRet;
				return csRet;
			}
			else if ( nOrgLength == 0 )
				return _T("");
			else
				return (LPCTSTR)lpszOrg;
		}

		if ( nOrgLength < 0 )
			nOrgLength = (int)strlen((const char*)lpszOrg);
		int nWideCount = nOrgLength + 1;
		WCHAR *wchar = new WCHAR[nWideCount];
		if ( !wchar ) return _T("");
		memset ( wchar, 0, nWideCount*sizeof(WCHAR) );
		::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpszOrg, nOrgLength, wchar, nWideCount);
		CString csRet = wchar;
		delete[] wchar;
		return csRet;
#else
		if ( !bOrgIsUnicode )
		{
			if ( nOrgLength > 0 )
			{
				char *szRet = new char[nOrgLength+1];
				if ( !szRet ) return _T("");
				memset ( szRet, 0, (nOrgLength+1)*sizeof(char) );
				memcpy ( szRet, lpszOrg, nOrgLength*sizeof(char) );
				CString csRet = szRet;
				delete[] szRet;
				return csRet;
			}
			else if ( nOrgLength == 0 )
				return _T("");
			else
				return (LPCTSTR)lpszOrg;
		}

		if ( nOrgLength < 0 )
			nOrgLength = (int)wcslen((WCHAR*)lpszOrg);
		int nMultiByteCount = nOrgLength + 1;
		char *szMultiByte = new char[nMultiByteCount];
		if ( !szMultiByte ) return _T("");
		memset ( szMultiByte, 0, nMultiByteCount*sizeof(char) );
		::WideCharToMultiByte ( CP_ACP, 0, (LPCWSTR)lpszOrg, nOrgLength, (LPSTR)szMultiByte, nMultiByteCount, NULL, NULL );
		CString csRet = szMultiByte;
		delete[] szMultiByte;
		return csRet;
#endif
	}
	CATCH_ALL(e)
	{
		HwDbgLog ( L_ERROR, _T("In GetCompatibleString() function module") );
		THROW_LAST ();
	}
	END_CATCH_ALL

	return _T("");
}

/********************************************************************************
* Function Type	:	global
* Parameter		:	hWnd			-	要激活的窗口句柄
*					bReShowWindow	-	再次调用ShowWindow()函数来显示窗口
* Return Value	:	None
* Description	:	激活一个窗口并获取输入焦点
*********************************************************************************/
#ifndef WINCE
void ActiveWindowAndHoldFocus ( HWND hWnd, BOOL bReShowWindow/*=TRUE*/ )
{
	DWORD ThreadID1,ThreadID2;
	long nRet;
	
	//Nothing to do if already in foreground.
	if(hWnd == GetForegroundWindow())
		return;
	//First need to get the thread responsible for this window,
	//and the thread for the foreground window.
	ThreadID1 = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
	ThreadID2 = GetWindowThreadProcessId(hWnd, NULL);
	//By sharing input state, threads share their concept of
	//the active window.
	if(ThreadID1 != ThreadID2)
	{
		AttachThreadInput(ThreadID1, ThreadID2, TRUE);
		nRet = SetForegroundWindow(hWnd);
		AttachThreadInput(ThreadID1, ThreadID2, FALSE);
	}
	else
	{
		nRet = SetForegroundWindow(hWnd);
	}
	
	if ( bReShowWindow )
	{
		//Restore and repaint
		if(IsIconic(hWnd))		//窗口是最小化的
			ShowWindow(hWnd, SW_RESTORE);
		else
			ShowWindow(hWnd, SW_SHOW);
	}
}
#endif

//
// 激活一个窗口,让它出现在所有窗口的前面
//
void ActiveWindowToForeground ( HWND hWnd )
{
	ASSERT ( ::IsWindow ( hWnd ) );
	::SetForegroundWindow ( hWnd );
	::SetActiveWindow ( hWnd );
	// 总在最前面,又放回去
	::SetWindowPos ( hWnd, HWND_TOPMOST ,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
	::SetWindowPos ( hWnd, HWND_NOTOPMOST ,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
	
}

//
// 模拟鼠标左键点击
//
void MouseLeftClick ( CPoint &pt )
{
	CPoint ptCur;
	::GetCursorPos ( &ptCur );
	::SetCursorPos ( pt.x, pt.y );
	mouse_event ( MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTDOWN, pt.x, pt.y,0,0);
	mouse_event ( MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTUP, pt.x, pt.y,0,0);
	::SetCursorPos ( ptCur.x, ptCur.y );
}

//
// 模拟键盘事,输入“+_”这几个字符会有问题
//
const char *szShiftChars	= "~!@#$%^&*()_+|}{\":?><";
const char *szNonShiftChars	= "`1234567890-=\\][\';/.,";
void KeyboardEvent ( BYTE bVk )
{
	BOOL bNeedShift = FALSE;
	if ( bVk >= 'a' && bVk <= 'z' )
	{
		bVk = 'A' + (bVk-'a');
	}
	else if ( bVk >= 'A' && bVk <= 'Z' )
	{
		bNeedShift = TRUE;
	}
	else
	{
		for ( int i=0; szShiftChars[i] != '\0'; i++ )
		{
			if ( (BYTE)szShiftChars[i] == bVk )
			{
				bNeedShift = TRUE;
				bVk = szNonShiftChars[i];
				break;
			}
		}
	}

	if ( bNeedShift )
		keybd_event(VK_SHIFT,MapVirtualKey(VK_SHIFT,0),0,0);

	keybd_event(bVk,MapVirtualKey(bVk,0),0,0);
	keybd_event(bVk,MapVirtualKey(bVk,0),KEYEVENTF_KEYUP,0);

	if ( bNeedShift )
		keybd_event(VK_SHIFT,MapVirtualKey(VK_SHIFT,0),KEYEVENTF_KEYUP,0);
}

//
// 模拟组合按键
// 注意:输入以'\0'结束
//
void KeyboardCombineEvent ( BYTE bVk, ... )
{
	CByteArray ByteAry;
	va_list list;
	va_start( list, bVk );
	while ( bVk != '\0' )
	{
		ByteAry.Add ( bVk );
		bVk = va_arg ( list, BYTE );
	}
	va_end( list );
	
	for ( int i=0; i<ByteAry.GetSize(); i++ )
	{
		bVk = ByteAry.GetAt(i);
		keybd_event(bVk,MapVirtualKey(bVk,0),0,0);
	}
	for ( i=(int)ByteAry.GetSize()-1; i>=0; i-- )
	{
		bVk = ByteAry.GetAt(i);
		keybd_event(bVk,MapVirtualKey(bVk,0),KEYEVENTF_KEYUP,0);
	}
}

//
// 等待线程退出
//
BOOL WaitForThreadEnd ( HANDLE *phThread, DWORD dwWaitTime /*=10*1000*/ )
{
	BOOL bRet = TRUE;
	ASSERT ( phThread );
	if ( !(*phThread) ) return TRUE;
	if ( ::WaitForSingleObject ( *phThread, dwWaitTime ) == WAIT_TIMEOUT )
	{
		Log ( L_WARNING, _T("Terminate forcedly thread (HANDLE = 0x%x)"), *phThread );
		bRet = FALSE;
		::TerminateThread ( *phThread, 0 );
	}
	::CloseHandle ( *phThread );
	(*phThread) = NULL;
	return bRet;
}

CString FormatString ( LPCTSTR lpszStr, ... )
{
	TCHAR *buf = NULL;
	// 循环格式化字符串,如果缓冲不够则将缓冲加大然后重试以保证缓冲够用同时又不浪费
	for ( int nBufCount = 1024; nBufCount<5*1024*1024; nBufCount *= 2 )
	{
		buf = new TCHAR[nBufCount];
		if ( !buf )
		{
			::AfxThrowMemoryException ();
			return _T("");
		}
		memset ( buf, 0, nBufCount*sizeof(TCHAR) );
		
		va_list  va;
		va_start (va, lpszStr);
		int nLen = _vsnprintf_hw ((TCHAR*)buf, nBufCount-sizeof(TCHAR), lpszStr, va);
		va_end(va);
		if ( nLen >= 0 && nLen <= (int)(nBufCount-sizeof(TCHAR)) )
			break;
		delete[] buf; buf = NULL;
	}
	if ( !buf )
	{
		return _T("");
	}
	
	CString csMsg = buf;
	delete[] buf; buf = NULL;
	return csMsg;
}

//
// 将一个窗口真正擦除掉
//
void EraseBkgnd ( CWnd *pWnd )
{
	if ( !pWnd || !::IsWindow ( pWnd->m_hWnd ) )
		return;
	CWnd *pParent = pWnd->GetParent ();
	
	if ( !pParent || !::IsWindow ( pParent->m_hWnd ) )
	{
		pWnd->Invalidate ();
		return;
	}
	
	CRect rcParentErase;
	pWnd->GetWindowRect ( &rcParentErase );
	pParent->ScreenToClient ( &rcParentErase );
	rcParentErase.InflateRect ( 5, 5 );
	pParent->RedrawWindow ( &rcParentErase );
}

//
// 修改窗口的消息处理函数地址
//
void ChangeWindownProc ( HWND hWnd, FUNC_WindowProc *ppfnOrg, FUNC_WindowProc pfnNew )
{
	if ( IsWindow(hWnd) && ppfnOrg )
	{
		*ppfnOrg = (FUNC_WindowProc)::GetWindowLong ( hWnd, GWL_WNDPROC );
		::SetWindowLong ( hWnd, GWL_WNDPROC, (LONG)pfnNew );
	}
}

CString GetWindowClassName ( HWND hWnd )
{
	if ( !IsWindow(hWnd) ) return _T("");
	TCHAR szClassName[255] = {0};
	::GetClassName ( hWnd, szClassName, COUNT(szClassName) );
	return szClassName;
}

CString GetWindowText ( HWND hWnd )
{
	if ( !IsWindow(hWnd) ) return _T("");
	TCHAR szTitle[255] = {0};
	::SendMessage(hWnd,WM_GETTEXT,COUNT(szTitle),(LPARAM)szTitle);
	return szTitle;
}

//
// 字符串反向查找
//
int StringReverseFind ( LPCTSTR lpszOrgStr, LPCTSTR lpszFindStr, int nStartPos/*=-1*/, BOOL bIgnoreCase/*=FALSE*/ )
{
	if ( !lpszOrgStr ) return -1;
	int nOrgStrLen = lstrlen(lpszOrgStr);
	if ( nOrgStrLen < 1 ) return -1;

	if ( !lpszFindStr ) return -1;
	int nFindStrLen = lstrlen(lpszFindStr);
	if ( nFindStrLen < 1 ) return -1;

	int nFindPos = -1;
	TRY
	{
		CString csSubString;
		if ( nStartPos < 0 ) nStartPos = nOrgStrLen-1;
		for ( int i=nStartPos; i>=0; i-- )
		{
			csSubString.Insert ( 0, lpszOrgStr[i] );
			if ( csSubString.GetLength() == nFindStrLen )
			{
				if ( (bIgnoreCase && csSubString.CompareNoCase(lpszFindStr) == 0) ||
					(!bIgnoreCase && csSubString.Compare(lpszFindStr) == 0) )
				{
					nFindPos = i;
					break;
				}
				csSubString.Delete ( csSubString.GetLength()-1 );
			}
		}
	}
	CATCH (CMemoryException, e)
	{
		nFindPos = -1;
	}
	END_CATCH;

	return nFindPos;
}


//
// 计算字符串中某子字符串的个数
//
int CalcSubStringCount ( LPCTSTR lpszText, LPCTSTR lpszSubString )
{
	if ( !lpszText || lstrlen(lpszText) < 1 ) return 0;
	if ( !lpszSubString || lstrlen(lpszSubString) < 1 ) return 0;
	
	CString csText = lpszText;
	CString csSubStr = lpszSubString;
	int nFindPos = 0;
	int nCount = 0;
	while ( TRUE )
	{
		nFindPos = csText.Find ( csSubStr, nFindPos );
		if ( nFindPos < 0 ) break;
		nCount  ++;
		nFindPos += csSubStr.GetLength();
	}
	return nCount;
}

BOOL StringIsDigit ( LPCTSTR lpszOrgStr )
{
	if ( !lpszOrgStr || lstrlen(lpszOrgStr) < 1 ) return FALSE;
	for ( int i=0; lpszOrgStr[i] != _T('\0'); i++ )
	{
		if ( lpszOrgStr[i] < 0 ) return FALSE;
		else if ( !isdigit_hw ( lpszOrgStr[i] ) ) return FALSE;
	}
	
	return TRUE;
}

ENUM_STRING_TIME_FORMAT GetStringTimeFormat ( LPCTSTR lpszString )
{
	if ( !lpszString ) return STRING_IS_COMMON;
	int nStrLen = lstrlen(lpszString);
	if ( nStrLen < 8 ) return STRING_IS_COMMON;

	if ( nStrLen == 19 )
	{
		if	(
			// 0~3:数字
			isdigit_hw(lpszString[0]) && isdigit_hw(lpszString[1]) && isdigit_hw(lpszString[2]) && isdigit_hw(lpszString[3]) &&
			// 4~4:'-'
			lpszString[4] == _T('-') &&
			// 5~6:数字
			isdigit_hw(lpszString[5]) && isdigit_hw(lpszString[6]) &&
			// 7~7:'-'
			lpszString[7] == _T('-') &&
			// 8~9:数字
			isdigit_hw(lpszString[8]) && isdigit_hw(lpszString[9]) &&
			// 10~10:' '
			lpszString[10] == _T(' ') &&
			// 11~12:数字
			isdigit_hw(lpszString[11]) && isdigit_hw(lpszString[12]) &&
			// 13~13:':'
			lpszString[13] == _T(':') &&
			// 14~15:数字
			isdigit_hw(lpszString[14]) && isdigit_hw(lpszString[15]) &&
			// 16~16:':'
			lpszString[16] == _T(':') &&
			// 17~18:数字
			isdigit_hw(lpszString[17]) && isdigit_hw(lpszString[18])
			)
			return STRING_IS_DATE_TIME;
	}

	if ( nStrLen == 10 )
	{
		if	(
			// 0~3:数字
			isdigit_hw(lpszString[0]) && isdigit_hw(lpszString[1]) && isdigit_hw(lpszString[2]) && isdigit_hw(lpszString[3]) &&
			// 4~4:'-'
			lpszString[4] == _T('-') &&
			// 5~6:数字
			isdigit_hw(lpszString[5]) && isdigit_hw(lpszString[6]) &&
			// 7~7:'-'
			lpszString[7] == _T('-') &&
			// 8~9:数字
			isdigit_hw(lpszString[8]) && isdigit_hw(lpszString[9])
			)
			return STRING_IS_ONLY_DATE;
	}

	if ( nStrLen == 8 )
	{
		if	(
			// 0~1:数字
			isdigit_hw(lpszString[0]) && isdigit_hw(lpszString[1]) &&
			// 2~2':'
			lpszString[2] == _T(':') &&
			// 3~4:数字
			isdigit_hw(lpszString[3]) && isdigit_hw(lpszString[4]) &&
			// 5~5:':'
			lpszString[5] == _T(':') &&
			// 6~7:数字
			isdigit_hw(lpszString[6]) && isdigit_hw(lpszString[7])
			)
			return STRING_IS_ONLY_TIME;
	}

	return STRING_IS_COMMON;
}


int hwSnprintfA ( char* buffer, int count, char* format, ... )
{
	if ( count < 1 ) return 0;
	ASSERT_ADDRESS ( buffer, count*sizeof(char) );
	memset ( buffer, 0, count*sizeof(char) );
	// 格式化
	va_list  va;
	va_start (va, format);
	int nRet = _vsnprintf ( buffer, count, format, va);
	va_end(va);
	buffer [count-1] = '\0';
	
	int nLen = nRet;
	if ( nLen < 0 ) nLen = (int)strlen(buffer);
	if ( nLen > count ) nLen = count;
	
	return nLen;
}

//
// 注意: count 参数不能用 sizeof(buffer) 来求得,而是用 sizeof(buffer)/sizeof(WCHAR) 来求得
//
int hwSnprintfW ( WCHAR* buffer, int count, WCHAR* format, ... )
{
	if ( count < 1 ) return 0;
	ASSERT_ADDRESS ( buffer, count*sizeof(WCHAR) );
	memset ( buffer, 0, count*sizeof(WCHAR) );
	// 格式化
	va_list  va;
	va_start (va, format);
	int nRet = _vsnwprintf ( buffer, count, format, va);
	va_end(va);
	buffer [count-1] = L'\0';
	
	int nLen = nRet;
	if ( nLen < 0 ) nLen = (int)wcslen(buffer);
	if ( nLen > count ) nLen = count;
	
	return nLen;
}

/********************************************************************************
* Function Type	:	Global
* Parameter		:	t			-	待处理的时间(秒)
*					buf			-	表示时间的字符串
*					Flag		-	标志
*									0	-	"2001-08-09 18:03:30"
*									1	-	"200108"
*									2	-	"0108"
*									3	-	"20010809"
*									4	-	"Wed. P.M. 06:03" 翻译成中文:"星期三 下午 06:03"
*									5	-	"18:03"
*									6	-	"2001-08-09"
*									7	-	"08/09"
*									8	-	"08/09(Wed.) P.M. 06:03" 翻译成中文:"08/09(星期三) 下午 06:03"
*									9	-	"08-09 18:03"
*									10	-	"2001-08"
*									11	-	"09180330"
*									12	-	"2001-08-09 18_03_30"
* Return Value	:	return the string length.
* Description	:	将一个time_t格式的时间值转换成相应的字符串(按年、月、日、时、
*					分、秒的顺序,年用四个字符,其他项用两个字符表示)
*********************************************************************************/
int ConvertTimeToStr(time_t t, TCHAR *buf, int nSize, int Flag /* = 0 */)
{
	ASSERT_ADDRESS ( buf, DATETIME_TYPE_COUNT );
	
	if(t < 1)
	{
		lstrcpyn ( buf, _T(""), nSize/sizeof(TCHAR) );
		ASSERT ( FALSE );
		return 0;
	}
	CTime cTime ( t );
	switch ( Flag )
	{
	case 0:
	default:
		return SnprintfHw( (LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%Y-%m-%d %H:%M:%S") ) );
	case 1:
		return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%Y%m") ) );
	case 2:
		return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%y-%m") ) );
	case 3:
		return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%Y%m%d") ) );
	case 4:
		{
			return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s %s %.2d:%.2d"), 
				f_WeekStr [ cTime.GetDayOfWeek() ], f_PAM[(cTime.GetHour()>=12)?1:0], cTime.GetHour()%12, cTime.GetMinute() );
		}
	case 5:
		return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%H:%M") ) );
	case 6:
		return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%Y-%m-%d") ) );
	case 7:
		return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%m/%d") ) );
	case 8:
		{
			return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%.2d/%.2d(%s) %s %.2d:%.2d"), 
				cTime.GetMonth(), cTime.GetDay(), f_WeekStr [ cTime.GetDayOfWeek() ],
				f_PAM[(cTime.GetHour()>=12)?1:0],
				cTime.GetHour()%12, cTime.GetMinute() );
		}
	case 9:
		return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%m-%d %H:%M") ) );
	case 10:
		return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%Y-%m") ) );
	case 11:
		return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%d%H%M%S") ) );
	case 12:
		return SnprintfHw((LPTSTR)buf, nSize/sizeof(TCHAR), _T("%s"), cTime.Format ( _T("%Y-%m-%d %H_%M_%S") ) );
	}
	
	return 0;
}

CString ConvertTimeToStr(time_t t, int Flag /*=0*/)
{
	if ( t < 1 ) return _T("");
	TCHAR buf[256] = {0};
	ConvertTimeToStr ( t, buf, sizeof(buf), Flag );
	return buf;
}

BOOL IsFileExist ( LPCTSTR lpszFileName )
{
	if ( !lpszFileName || lstrlen(lpszFileName) < 1 ) return FALSE;
	CFileStatus status;
	BOOL bRet = TRUE;
	TRY
	{
		if ( !CFile::GetStatus(lpszFileName, status) )
		{
			bRet = FALSE;
		}
	}
	CATCH (CFileException, e)
	{
		bRet = FALSE;
	}
	CATCH_ALL(e)
	{
		bRet = FALSE;
	}
	END_CATCH_ALL;
	
	//	if ( status.m_size <= 0 ) return   FALSE;
	
	return  bRet;
}

//
// 将窗口透明化
//
void TransparentWindow ( HWND hWnd, BYTE bAlpha/*0~255*/ )
{
	if ( !IsWindow(hWnd) ) return;
	SetWindowLong(hWnd,GWL_EXSTYLE, GetWindowLong(hWnd,GWL_EXSTYLE)^0x80000);
	HINSTANCE hInst = LoadLibrary("User32.DLL");
	if(hInst)
	{
		typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD);
		MYFUNC fun = NULL;
		// 取得SetLayeredWindowAttributes函数指针 
		fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");
		if(fun)fun(hWnd,0,bAlpha,2); 
		FreeLibrary(hInst);
	}
}

/********************************************************************************
* Function Type	:	Global
* Parameter		:	lpFileName	-	文件路径
* Return Value	:	-1			-	失败
*					>=0			-	文件大小
* Description	:	获取文件属性 ( 文件大小、创建时间 )
*********************************************************************************/
int hwGetFileAttr ( LPCTSTR lpFileName, OUT CFileStatus *pFileStatus/*=NULL*/ )
{
	if ( !lpFileName || lstrlen(lpFileName) < 1 ) return -1;
	
	CFileStatus fileStatus;
	fileStatus.m_attribute = 0;
	fileStatus.m_size = 0;
	memset ( fileStatus.m_szFullName, 0, sizeof(fileStatus.m_szFullName) );
	BOOL bRet = FALSE;
	TRY
	{
		if ( CFile::GetStatus(lpFileName,fileStatus) )
		{
			bRet = TRUE;
		}
	}
	CATCH (CFileException, e)
	{
		ASSERT ( FALSE );
		bRet = FALSE;
	}
	CATCH_ALL(e)
	{
		ASSERT ( FALSE );
		bRet = FALSE;
	}
	END_CATCH_ALL;
	
	if ( pFileStatus )
	{
		pFileStatus->m_ctime = fileStatus.m_ctime;
		pFileStatus->m_mtime = fileStatus.m_mtime;
		pFileStatus->m_atime = fileStatus.m_atime;
		pFileStatus->m_size = fileStatus.m_size;
		pFileStatus->m_attribute = fileStatus.m_attribute;
		pFileStatus->_m_padding = fileStatus._m_padding;
		lstrcpy ( pFileStatus->m_szFullName, fileStatus.m_szFullName );
		
	}
	
	return (int)fileStatus.m_size;
}

/********************************************************************************
* Function Type	:	Global
* Parameter		:	lpFileName	-	文件路径
* Return Value	:	成功 / 失败
* Description	:	设置文件属性 ( 创建时间、文件属性等 )
*********************************************************************************/
BOOL hwSetFileAttr (
					LPCTSTR lpFileName,
					int nAttribute/*=-1*/,
					time_t tModifiedTime/*=0*/,
					time_t tLastCreateTime/*=0*/,
					time_t tLastAccessTime/*=0*/
					)
{
	if ( !lpFileName || lstrlen(lpFileName) < 1 ) return FALSE;
	
	// 从文件中获取当前属性
	CFileStatus fileStatus;
	if ( hwGetFileAttr ( lpFileName, &fileStatus ) < 0 )
		return FALSE;
	
	// 得到文件日期信息
	if ( tModifiedTime > 0 ) fileStatus.m_mtime = tModifiedTime;
	if ( tLastCreateTime > 0 ) fileStatus.m_ctime = tLastCreateTime;
	if ( tLastAccessTime > 0 ) fileStatus.m_atime = tLastAccessTime;
	
	if ( fileStatus.m_mtime.GetTime() <= 0 ) fileStatus.m_mtime = GetCurrentTimeHw();
	if ( fileStatus.m_ctime.GetTime() <= 0 ) fileStatus.m_ctime = fileStatus.m_mtime;
	if ( fileStatus.m_atime.GetTime() <= 0 ) fileStatus.m_ctime = fileStatus.m_atime;
	
	// 得到文件属性信息
	if ( nAttribute >= 0 )
		fileStatus.m_attribute = (BYTE)nAttribute;
	
	// 设置文件属性
	BOOL bRet = FALSE;
	TRY
	{
		CFile::SetStatus ( lpFileName, fileStatus );
		bRet = TRUE;
	}
	CATCH (CFileException, e)
	{
		bRet = FALSE;
	}
	CATCH_ALL(e)
	{
		bRet = FALSE;
	}
	END_CATCH_ALL;
	
	return bRet;
}

long atoi_hw ( char *szStr, int nRadix/*=10*/ )
{
	if ( !szStr ) return 0;
	char *pEndPtr = NULL;
	return strtoul ( szStr, &pEndPtr, nRadix );
}

long atoi_hw ( WCHAR *szStr, int nRadix/*=10*/ )
{
	if ( !szStr ) return 0;
	CMultiByteString cbsStr ( (LPCTSTR)szStr );
	return atoi_hw ( cbsStr.GetBuffer() );
}

long atoi_hw ( LPCTSTR lpszStr, int nRadix/*=10*/ )
{
	if ( !lpszStr ) return 0;
#ifdef UNICODE
	return atoi_hw ( (WCHAR*)lpszStr, nRadix );
#else
	return atoi_hw ( (char*)lpszStr, nRadix );
#endif
}

//
// 净化字符串
//
CString CleanseString(CString &cs, LPCTSTR lpszApp/*=NULL*/)
{
	if ( cs.IsEmpty() ) return _T("");
	cs.TrimLeft ();
	cs.TrimRight ();
	if ( lpszApp && lstrlen(lpszApp) > 0 )
	{
		cs.TrimLeft ( lpszApp );
		cs.TrimRight ( lpszApp );
	}
	return cs;
}