📄 gethz.cpp
字号:
//根据输入的英文编码串,得到其汉字
#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 ='\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<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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -