GETHZ.CPP
上传用户:zhang8947
上传日期:2007-01-08
资源大小:1910k
文件大小:13k
- //根据输入的英文编码串,得到其汉字
- #include "stdafx.h"
- #include <windowsx.h>
- #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<nNum ; i++ ) //对剩余的字母一一进行检索
- {
- //判断是否到达库尾
- while( OInputLib.m_dwContent < OInputLib.m_dwLibLen )
- {
- if( OInputLib.m_hpsContent[OInputLib.m_nCheckedNum+1] & 0x80 )
- {
- //是汉字,库中的串较小,往下走指针
- OInputLib.m_dwContent +=(BYTE)(*OInputLib.m_hpsContent) ;
- OInputLib.m_hpsContent +=(BYTE)(*OInputLib.m_hpsContent) ;
- continue ;
- }
-
- //进行比较
- n =hstrncmp( OInputLib.m_hpsContent+1 , //库中的英文串
- (char huge*)lpsEnglish , OInputLib.m_nCheckedNum+1 ) ;
- if( !n ) //匹配成功
- {
- //设置内容指针,为了以后回溯
- OInputLib.m_dwContentPoint[OInputLib.m_nCheckedNum++] =
- OInputLib.m_dwContent ;
- if( i<nNum-1 ) //还没到最后一个字母,继续检索
- break ; //进入下一循环
-
- //已经是最后一个字母,设置翻页指针
- 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( n>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<nItemLen ; i++ )
- if( hps[i] == ' ' )
- j++ ;
- //判断长度是否已经超出
- if( nReturnLen+nItemLen+j > nMaxChinese ) //长度已经超出
- {
- *lpnChineseLen =nReturnLen ;
- return 1 ; //没有到底
- }
- //长度没有超出,得到这些词组
- lpsChinese[nReturnLen++] =cWordNum++ ; //序号
- for( i=0 ; i<nItemLen ; i++ )
- {
- lpsChinese[nReturnLen++] =hps[i] ;
- if( hps[i] == ' ' )
- lpsChinese[nReturnLen++] =cWordNum++ ; //序号
- }
- //往下走页指针
- OInputLib.m_dwPage +=(BYTE)*OInputLib.m_hpsPage ;
- OInputLib.m_hpsPage =hps+nItemLen ;
- //判断新的项是否满足要求
- //进行比较
- n =hstrncmp( OInputLib.m_hpsPage + 1 , //库中的英文串
- (char huge*)lpsEnglish , nEnglishLen ) ;
- if( n ) //不相等,说明不可能再匹配,也不能再往下翻了
- {
- *lpnChineseLen =nReturnLen ;
- return 0 ;
- }
-
- if( nReturnLen >= 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 ; ) //判断是否已经有词组了
- {
- for( k=j+2 ; k<nReturnLen ; k+=2 )
- if( lpsChinese[k]==' ' )
- break ;
- if( k>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<i ; j++ )
- lpsChinese[nReturnLen++] =hps[j] ;
- }
- //往下走页指针
- OInputLib.m_dwPage +=nItemLen + i ;
- OInputLib.m_hpsPage =hps+i ;
- //判断是空格结束还是一项结束
- if( hps[i+1] & 0x80 ) //是空格结束
- continue ;
-
- //判断新的项是否满足要求
- //进行比较
- n =hstrncmp( OInputLib.m_hpsPage + 1 , //库中的英文串
- (char huge*)lpsEnglish , nEnglishLen ) ;
- if( n ) //不相等,说明不可能再匹配,也不能再往下翻了
- {
- *lpnChineseLen =nReturnLen ;
- return 0 ;
- }
-
- if( nReturnLen >= 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<nEnglishLen ; i++ )
- {
- n =lpsEnglish[i] - START_CODE ;
- if( n<0 || n>=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 =' ' ;
- return ;
- }
- //长度
- int n =min( nMaxNameLen-1 ,
- strlen(OInputLib.m_lpLibHead->sName));
- _fstrncpy( lpsName , OInputLib.m_lpLibHead->sName , n ) ;
- lpsName[n] =' ' ; //结束
- }
- //得到输入法最大输入长度
- 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<n ; i++ )
- {
- if( s1[i] == s2[i] )
- continue ;
- if( s1[i] < s2[i] ) //s1比s2小
- return -1 ;
- return 1 ; //s1比s2大
- }
- return 0 ; //两者相等
- }
-
- #ifdef __cplusplus
- }
- #endif
-