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 ; i 0 ) //库中的串较大,说明不可能匹配 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 ; j nReturnLen ) 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