www.pudn.com > 智能内码识别,支持屏幕取词翻译的程序.zip > GETHZ.CPP


//根据输入的英文编码串,得到其汉字 
#include	"stdafx.h" 
#include	 
 
#include	"gethz.h" 
#include	"csinput.h" 
 
CInputLib	OInputLib ;		//输入法库对象 
 
CInputLib::CInputLib( void ) 
{ 
	m_hpsLib	=NULL ; 
	m_dwLibLen	=0 ; 
	m_lpLibHead	=NULL ; 
} 
 
CInputLib::~CInputLib( void ) 
{ 
	if( m_hpsLib ) 
		GlobalFreePtr( m_hpsLib ) ; 
} 
 
//装入输入法库 
BOOL	CInputLib::LoadInputLib( LPCSTR lpsLibName ) 
{ 
	CFile	file ; 
 
	//打开输入法文件	 
	if( !file.Open( lpsLibName , CFile::modeRead|CFile::typeBinary ) ) 
	{ 
		AfxMessageBox( "输入法文件打开出错" ) ; 
		return	0 ; 
	} 
	//得到文件长度 
	m_dwLibLen	=file.GetLength() ; 
	if( m_dwLibLen < sizeof( INPUT_LIB_HEAD ) ) 
	{ 
		AfxMessageBox( "文件长度不对!" ) ; 
		file.Close() ; 
		return	0 ; 
	} 
	//分配库所需的空间 
	m_hpsLib	=(char huge*)GlobalAllocPtr( GMEM_FIXED ,  
							m_dwLibLen ) ; 
	if( !m_hpsLib ) 
	{ 
		AfxMessageBox( "内存不够,无法装入输入法库!" ) ; 
		file.Close() ; 
		return	0 ; 
	} 
	//读出输入法库 
	file.ReadHuge( m_hpsLib , m_dwLibLen ) ; 
	//关闭文件 
	file.Close() ; 
	 
	//库头 
	m_lpLibHead	=(INPUT_LIB_HEAD far*)m_hpsLib ; 
	 
	return	1 ; 
} 
 
//卸掉输入法库 
void	CInputLib::UnloadInputLib( void ) 
{ 
	if( m_hpsLib ) 
	{ 
		GlobalFreePtr( m_hpsLib ) ; 
		m_hpsLib	=NULL ; 
		m_dwLibLen	=0 ; 
	} 
} 
 
//-------------------------------------------------------------------------// 
 
#ifdef	__cplusplus 
extern	"C"	{ 
#endif 
 
//装入输入法库 
BOOL __export FAR PASCAL LoadInputLib( LPCSTR lpsLibName ) 
{ 
	return	OInputLib.LoadInputLib( lpsLibName ) ; 
} 
 
//卸掉输入法库 
void __export FAR PASCAL	UnloadInputLib( void ) 
{ 
	OInputLib.UnloadInputLib() ; 
} 
 
//根据输入的英文编码,得到汉字 
//nFlag=0,从头开始查,设置翻页指针 
//nFlag=1,从以前的继续查,设置翻页指针 
//nFlag=2,往回走一个字母,设置翻页指针 
//nFlag=3,向下翻页,只改变翻页指针,但不改变查找用的指针 
//nFlag=4,向上翻页 
//返回0:出错 
//返回1:只可以向下翻页 
//返回2:只可以向上翻页 
//返回3:可以向下也可以向上翻页 
//返回4:不能进行翻页 
int	__export	FAR PASCAL	GetOutputHz(  
						LPCSTR lpsEnglish , int nEnglishLen , 
						LPSTR lpsChinese , int	nMaxChinese , 
						LPINT lpnChineseLen , int nFlag ) 
{ 
	int	i , n , nNum ; 
 
	if( nFlag == 3 || nFlag == 4 )	//只是翻页而已 
		//组织返回汉字串 
		return	ArrangeOutHz( lpsEnglish , nEnglishLen , 
								lpsChinese , nMaxChinese , lpnChineseLen , 
											nFlag ) ; 
	 
	if( !CheckInput( lpsEnglish , nEnglishLen ) )	//检查输入串的合法性 
		return	0 ;		//不合法 
	if( !OInputLib.m_lpLibHead->dwIndex[lpsEnglish[0]-START_CODE] ) 
		goto l100 ;	//没有该项 
 
	if( nFlag == 2 )	//往回走一个字母 
	{ 
		if( !OInputLib.m_nCheckedNum )	//没有字母被检索过 
		{ 
			AfxMessageBox( "还没有字母被检索过呢,就要往回走了?" ) ; 
			return	0 ; 
		} 
		OInputLib.m_nCheckedNum-- ;		//减少检索过的字母 
		if( !OInputLib.m_nCheckedNum )		//只有一个检索过的字母 
		{ 
			AfxMessageBox( "只检索过一个字母,不应该让我处理的!" ) ; 
			*lpnChineseLen	=0 ; 
			return	1 ; 
		} 
		 
		//重新设置内容指针 
		OInputLib.m_dwContent	= 
					OInputLib.m_dwContentPoint[OInputLib.m_nCheckedNum-1] ; 
		OInputLib.m_hpsContent	=OInputLib.m_hpsLib + 
													OInputLib.m_dwContent ; 
						 
		//设置页指针 
		OInputLib.m_hpsPage	=OInputLib.m_hpsContent ; 
		OInputLib.m_dwPage	=OInputLib.m_dwContent ; 
		OInputLib.m_nScrolledPage	=0 ;	//已经翻过的页数 
	 
		//组织返回汉字串 
		return	ArrangeOutHz( lpsEnglish , nEnglishLen , 
								lpsChinese , nMaxChinese , lpnChineseLen , 
											3 ) ;		//向下翻页 
	} 
		 
	if( !nFlag )		//表示根据英文编码,从头查 
	{ 
		OInputLib.m_dwContent	=OInputLib.m_lpLibHead-> 
									dwIndex[lpsEnglish[0]-START_CODE] ; 
		//设置好库内容指针 
		OInputLib.m_hpsContent	=OInputLib.m_hpsLib +  
													OInputLib.m_dwContent ; 
 
		//记录内容指针位置 
		OInputLib.m_dwContentPoint[0]	=OInputLib.m_dwContent ;									 
		OInputLib.m_nCheckedNum	=1 ;	//已经检索过的字母数 
	} 
	 
	//检索余下的字母 
	nNum	=nEnglishLen-OInputLib.m_nCheckedNum ;	//剩余的字母数 
	if( !nNum )	//已经没有剩余字母 
	{ 
		//设置翻页指针,从头翻起 
		OInputLib.m_dwPage	=OInputLib.m_dwContent ; 
		OInputLib.m_hpsPage	=OInputLib.m_hpsContent ; 
		//记录翻页指针位置 
		OInputLib.m_nScrolledPage	=0 ;	//已经翻过的页数 
		//组织返回汉字串 
		return	ArrangeOutHz( lpsEnglish , nEnglishLen , 
							lpsChinese , nMaxChinese , lpnChineseLen , 
											3 ) ;	//向下翻页 
	} 
 
	for( i=0 ; i0 )		//库中的串较大,说明不可能匹配 
				goto	l100 ; 
				 
			//库中的串较小,往下走指针 
			OInputLib.m_dwContent	+=(BYTE)(*OInputLib.m_hpsContent) ; 
			OInputLib.m_hpsContent	+=(BYTE)(*OInputLib.m_hpsContent) ; 
		} 
	} 
	 
	//找不到 
l100:	OInputLib.m_nCheckedNum	=nEnglishLen ; 
	*lpnChineseLen	=0 ; 
	return 4 ; 
} 
 
//组织返回汉字串 
//nFlag=3,向下翻页 
//nFlag=4,向上翻页 
//返回0:出错 
//返回1:只可以向下翻页 
//返回2:只可以向上翻页 
//返回3:可以向下也可以向上翻页 
//返回4:不能进行翻页 
int	ArrangeOutHz( LPCSTR lpsEnglish , int nEnglishLen , 
							LPSTR lpsChinese , int nMaxChinese ,  
							LPINT lpnChineseLen , int nFlag ) 
{ 
	if( nFlag == 4 )	//向上翻页 
	{ 
		if( OInputLib.m_nScrolledPage<=1 )		//无页可翻 
		{ 
			AfxMessageBox( "到头了,你还让我翻?" ) ; 
			return	0 ; 
		} 
		 
		OInputLib.m_nScrolledPage-- ;	//往回翻 
		//调整页指针 
		OInputLib.m_dwPage	= 
				OInputLib.m_dwPagePoint[OInputLib.m_nScrolledPage-1] ; 
		OInputLib.m_hpsPage	=OInputLib.m_hpsLib + OInputLib.m_dwPage ; 
 
		//读取汉字串 
		SetHzString( lpsEnglish , nEnglishLen , 
							lpsChinese , nMaxChinese , lpnChineseLen ) ; 
		if( OInputLib.m_nScrolledPage<=1 )	//已经到头了 
			return	1 ;		//只可以向下翻了 
			 
		return	3 ;		//可以前后翻 
	} 
	 
	//是向下翻页 
	//设置翻页指针 
	OInputLib.m_dwPagePoint[OInputLib.m_nScrolledPage++]	= 
		OInputLib.m_dwPage ; 
	//读取汉字串		 
	if( !SetHzString( lpsEnglish , nEnglishLen ,	//已经到底 
								lpsChinese , nMaxChinese , lpnChineseLen ) ) 
	{								 
		if( OInputLib.m_nScrolledPage <= 1 )	//只有一页 
			return	4 ;		//不能进行翻页 
		return	2 ;		//只能往上翻页 
	} 
 
	if( OInputLib.m_nScrolledPage <= 1 )	//只有一页,即当前显示页 
		return	1 ;	//只能往后翻页 
	 
	if( OInputLib.m_nScrolledPage >= MAX_PAGE )	//已经到最大页数 
		return	2 ;	//只能往前翻页 
		 
	return	3 ;		//可以前后翻页 
} 
 
//读取汉字串		 
//返回0:已经到底 
//返回1:没有到底 
/*int	SetHzString( LPCSTR lpsEnglish , int nEnglishLen , 
							LPSTR lpsChinese , int nMaxChinese ,  
							LPINT lpnChineseLen )  
{ 
	char huge	*hps ;	//指向项汉字 
	int		nItemLen ;	//项汉字长度	 
	int		i , j , n ; 
 
	int	nReturnLen	=0 ;	//返回的汉字串长度 
	char	cWordNum	='1'  ;	//词数 
	//判断是否到达库尾 
	while( OInputLib.m_dwPage < OInputLib.m_dwLibLen ) 
    { 
    	hps	=OInputLib.m_hpsPage+2 ;	//指向汉字串 
    	nItemLen	=(BYTE)(*OInputLib.m_hpsPage)-2 ;	//汉字串长度 
    	//去掉英文 
    	for( ; !( (*hps)&0x80 ) ; nItemLen-- , hps++ )	//是英文 
    		; 
    	if( nItemLen < 2 ) 
    	{ 
    		AfxMessageBox( "库中的汉字项不对!" ) ; 
    		return	0 ; 
    	} 
    	//分析汉字串 
    	//计算汉字串中有几种汉字词组(词组之间以空格格开) 
    	j	=1 ;	//至少一个 
    	for( i=2 ; i nMaxChinese )	//长度已经超出 
		{ 
			*lpnChineseLen	=nReturnLen ; 
			return	1 ;		//没有到底 
		} 
		//长度没有超出,得到这些词组 
		lpsChinese[nReturnLen++]	=cWordNum++ ;	//序号 
		for( i=0 ; i= nMaxChinese )	//长度到头了 
		{ 
			*lpnChineseLen	=nReturnLen ; 
			return	1 ; 
		} 
			 
		//两者相等,得到这些内容 
		lpsChinese[nReturnLen++]	=' ' ;		//加一个空格 
	} 
	 
	*lpnChineseLen	=nReturnLen ; 
	return	0 ;		//库结束了 
} 
*/ 
int	SetHzString( LPCSTR lpsEnglish , int nEnglishLen , 
							LPSTR lpsChinese , int nMaxChinese ,  
							LPINT lpnChineseLen )  
{ 
	char huge	*hps ;	//指向项汉字 
	int		nItemLen ;	//项汉字长度	 
	int		i , j , k , n , nFlag ; 
 
	int	nReturnLen	=0 ;	//返回的汉字串长度 
	char	cWordNum	='1'  ;	//词数 
	//判断是否到达库尾 
	while( OInputLib.m_dwPage < OInputLib.m_dwLibLen ) 
    { 
    	hps	=OInputLib.m_hpsPage ; 
    	//直到碰到汉字为止 
    	nItemLen	=0 ; 
    	for( ; !( (*hps)&0x80 ) || !( (*(hps+1))&0x80 ); hps++ , nItemLen++) 
    		;		//不是汉字 
    	//分析该汉字串,碰到非汉字时结束 
		for( i=2 ; (hps[i]&0x80)&&(hps[i+1]&0x80) ; i++ , i++ ) 
			; 
		//判断长度是否超出 
		if( nReturnLen+i+2 > nMaxChinese )	//长度已经超出 
		{ 
			*lpnChineseLen	=nReturnLen ; 
			return	1 ;		//没有到底 
		} 
		//长度没有超出,得到该词组 
		nFlag	=1 ;	//标记可以加入词组 
		for( j=1 ; jnReturnLen ) 
				break ; 
			//找到一个词组 
			if( !hstrncmp( lpsChinese+j , hps , k-j ) )	//相等 
			{ 
				nFlag	=0 ; 
				break ; 
			} 
			j	=k+2 ;	//跳过空格和下一个标号 
		} 
		 
		if( nFlag )	//可以加入该词组 
		{		 
			if( nReturnLen )	//不是开始,加空格 
				lpsChinese[nReturnLen++]	=' ' ; 
			lpsChinese[nReturnLen++]	=cWordNum++ ;	//序号 
			for( j=0 ; j= nMaxChinese )	//长度到头了 
		{ 
			*lpnChineseLen	=nReturnLen ; 
			return	1 ; 
		} 
	} 
	 
	*lpnChineseLen	=nReturnLen ; 
	return	0 ;		//库结束了 
} 
 
//检查输入串的合法性 
int __export FAR PASCAL	CheckInput( LPCSTR lpsEnglish ,  
																int nEnglishLen ) 
{ 
	if( !OInputLib.m_dwLibLen )		//当前没有装入输入法库 
	{ 
		AfxMessageBox( "还没有装入输入法库!" ) ; 
		return	0 ; 
	} 
	 
	if( nEnglishLen<=0 ) 
	{ 
		AfxMessageBox( "输入串长度不对!" ) ; 
		return	0 ; 
	} 
 
	int	n ;		 
	for( int i=0 ; i=CODE_CELL_NUM )		//超出了规定的字符范围 
		{ 
//			AfxMessageBox( "输入串不合法!" ) ; 
			return	0 ; 
		} 
 
		//当前输入法没有该字符			  
		if( !OInputLib.m_lpLibHead->sCodeCells[n] )	 
			return	0 ; 
	} 
			 
	return	1 ; 
} 
 
//得到有关输入法库的信息 
void	__export	FAR PASCAL	GetInputMethodName( LPSTR lpsName ,  
								int	nMaxNameLen ) 
{ 
	if( !OInputLib.m_hpsLib )		//还没有安装库 
	{ 
		AfxMessageBox( "还没有安装库呢!请先安装输入法库!" ) ; 
		*lpsName	='\0' ; 
		return	; 
	} 
 
	//长度	 
	int		n	=min( nMaxNameLen-1 ,  
							strlen(OInputLib.m_lpLibHead->sName)); 
	_fstrncpy( lpsName , OInputLib.m_lpLibHead->sName , n ) ; 
	lpsName[n]	='\0' ;		//结束 
} 
 
//得到输入法最大输入长度								 
int	__export FAR PASCAL GetInputMethodMaxLen( void ) 
{ 
	if( !OInputLib.m_hpsLib )		//还没有安装库 
	{ 
		AfxMessageBox( "还没有安装库呢!请先安装输入法库!" ) ; 
		return	0 ; 
	} 
 
	return	OInputLib.m_lpLibHead->nMaxCodeLen ; 
} 
 
//比较两个huge指针所指的字符串 
int	hstrncmp( char huge *s1 , char huge *s2 , int n ) 
{ 
	for( int i=0 ; i