⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tranuc.cpp

📁 支持Windows 3.x、Windows 9x平台上的中文(GB、Big5)、日文(Shift JIS、EUC JIS)、韩文(KS C 5601)、HZ码的显示与输入,智能内码识别
💻 CPP
字号:

//UCDOS输入法文本文件转换程序

#include	"stdafx.h"
#include	"windowsx.h"
#include	"tranuc.h"
#include	"csinput.h"

CTranUcdos	OTranUcdos ;

//转换的接口
BOOL	CTranUcdos::TranslateUcdos( CString pathName )
{
	//组织库文件名
	strcpy( m_sLibName , pathName ) ;
	m_sLibName[strlen(m_sLibName)-3]	='\0' ;
	strcat( m_sLibName , "iml" ) ;
		 
	//打开原文件
	CFile	file ;
	if( !file.Open( pathName , CFile::modeRead|CFile::typeBinary ) )
	{
		AfxMessageBox( "Open file error" ) ;
		return	0 ;
	}
	//得到文件长度
	m_dwSourceLen	=file.GetLength() ;
	//分配地址空间
	m_hpsSource	=(char huge*)GlobalAllocPtr( GMEM_FIXED ,
												m_dwSourceLen ) ;
	if( !m_hpsSource )
	{
		AfxMessageBox( "GlobalAllocPtr error" ) ;
		file.Close() ;
		return 0 ;
	}
	//读出源文件内容
	file.ReadHuge( m_hpsSource , m_dwSourceLen ) ;
	//关闭文件
	file.Close() ;
		
	//对源库进行分析,以生成我的库
	//设置初始值
	//整个库所占字节数
	inputLibHead.dwTotalBytes	=sizeof( INPUT_LIB_HEAD ) ;
	inputLibHead.dwTotalWords	=0 ;		//整个库中的词条数目
	inputLibHead.sName[0]		='\0' ;		//输入法名,以'\0'结束
	inputLibHead.nFunctionKey	=0 ;		//功能键号
	inputLibHead.nGodKey	='z' ;			//万能键
	inputLibHead.nMaxCodeLen	=0 ;	//最大码长
	for( int i=0 ; i<CODE_CELL_NUM ; i++ )
	{
		inputLibHead.sCodeCells[i]	=0 ;
		inputLibHead.dwIndex[i]	=0 ;	//首码索引表
	}
		
	Analysis() ;
		
	//释放申请的空间
	GlobalFreePtr( m_hpsSource ) ;
		
	//产生我的输入法文件
	CreateMyLib() ;

	
	return	1 ;
}

//创建我的输入法库
void	CTranUcdos::CreateMyLib( void )
{
	DWORD	dwLibPoint	=sizeof( INPUT_LIB_HEAD ) ;	//库指针
	char	sFileName[13]	="a.tmp" ;
	CFile	file ;
	DWORD	dwFileLen ;
	char huge	*hpsFile ;
	
	CFile	libFile ;	//库文件
	if( !libFile.Open( m_sLibName , CFile::modeReadWrite|
														CFile::modeCreate|
														CFile::typeBinary ) )
	{
		AfxMessageBox( "创建.iml文件失败" ) ;
		return	;
	}
	//将库头写入,主要是为了定位
	libFile.Write( &inputLibHead , sizeof( INPUT_LIB_HEAD ) ) ;
	
	INPUT_LIB_ITEM huge	*pItem ;
	DWORD	j ;
	DWORD	dwItemNum ;
	int	nItemLen ;
	
	for( int i=0 ; i<CODE_CELL_NUM ; i++ )
	{
		if( !inputLibHead.sCodeCells[i] )	//没有这个元
			continue ;

		//组织文件名
		sFileName[0]	=i+33 ;
		//打开文件
		if( !file.Open( sFileName , CFile::modeRead|CFile::typeBinary ) )
			continue ;		//可能该文件不存在

		//得到文件长度
		dwFileLen	=file.GetLength() ;
		if( dwFileLen % sizeof( INPUT_LIB_ITEM ) )
		{
			AfxMessageBox( "文件长度不对" ) ;
			return ;
		}
		//分配空间
		hpsFile	=(char huge*)GlobalAllocPtr( GMEM_FIXED ,
						                           	dwFileLen ) ;
		if( !hpsFile )
		{
			AfxMessageBox( "GlobalAllocPtr error" ) ;
			return ;
		}                                         
		//读出内容
		file.ReadHuge( hpsFile , dwFileLen ) ;
		//关闭文件
		file.Close() ;
		//删除该文件
		remove( sFileName ) ;
		
		//对该内容进行排序
		SortContent( hpsFile , dwFileLen ) ;
		
		//填写该码元检索表
		inputLibHead.dwIndex[i]	=dwLibPoint ;

		//将排序结果写入库文件
		dwItemNum	=dwFileLen/sizeof( INPUT_LIB_ITEM) ;
		pItem	=(INPUT_LIB_ITEM huge*)hpsFile ;
		for( j=0 ; j<dwItemNum ; j++ )
		{
			//项长度
			nItemLen	=1 + pItem->nEnglishLen + pItem->nChineseLen ;
			dwLibPoint	+=nItemLen ;	//修改库指针
			//写入项长度
			libFile.Write( &nItemLen , 1 ) ;
			//写入英文串
			libFile.Write( pItem->sEnglish , pItem->nEnglishLen ) ;
			//写入汉字串
			libFile.Write( pItem->sChinese , pItem->nChineseLen ) ;
			
			pItem++ ;
		}
		
		//释放空间
		GlobalFreePtr( hpsFile ) ;
	}

	//定位到库开始,重新写入库头
	libFile.SeekToBegin() ;
	libFile.Write( &inputLibHead , sizeof( INPUT_LIB_HEAD ) ) ;
	//关闭库文件
	libFile.Close() ;
	
	if( dwLibPoint != inputLibHead.dwTotalBytes )
		AfxMessageBox( "dwLibPoint!==dwTotalBytes" ) ;
}
		
//对该内容进行排序
void	CTranUcdos::SortContent( char huge *hpsFile , DWORD dwFileLen )
{
	int	nItemLen	=sizeof( INPUT_LIB_ITEM ) ;
	DWORD	dwItemNum	=dwFileLen/nItemLen ;	//项数
	INPUT_LIB_ITEM	huge *pItem1 ;
	INPUT_LIB_ITEM  huge *pItem2 ;	//排序用
	INPUT_LIB_ITEM	item ;	//排序用缓冲区
	DWORD	i , j ;
	int	n ;
	
	for( i=0 ; i<dwItemNum ; i++ )
	{
		pItem1	=(INPUT_LIB_ITEM huge*)( hpsFile + i*nItemLen ) ;
		for( j=i+1 ; j<dwItemNum ; j++ )
		{
			pItem2	=(INPUT_LIB_ITEM huge*)( hpsFile + j*nItemLen ) ;
		    //比较两者的编码
		    n	=_fstrncmp( pItem1->sEnglish , pItem2->sEnglish ,
		    					min( pItem1->nEnglishLen , pItem2->nEnglishLen ) ) ;
			if( !n )		//两者相等,长者在后,短者在前
			{
				if( pItem1->nEnglishLen > pItem2->nEnglishLen )	//交换
				{
					CopyInputItem( &item , pItem1 ) ;
					CopyInputItem( pItem1 , pItem2 ) ;
					CopyInputItem( pItem2 , &item ) ;
				}
				continue ;
			}
			
			if( n>0 )	//前者大,需要交换
			{
				CopyInputItem( &item , pItem1 ) ;
				CopyInputItem( pItem1 , pItem2 ) ;
				CopyInputItem( pItem2 , &item ) ;
		    }
		    //前者小,不需要交换
		}		  
	}
}

//拷贝输入项
void	CTranUcdos::CopyInputItem( INPUT_LIB_ITEM huge *item1 , 
									INPUT_LIB_ITEM huge *item2 )
{
	item1->nEnglishLen	=item2->nEnglishLen ;
	item1->nChineseLen	=item2->nChineseLen ;
	_fstrncpy( item1->sEnglish , item2->sEnglish , item2->nEnglishLen ) ;
	_fstrncpy( item1->sChinese , item2->sChinese , item2->nChineseLen ) ;
}									

void	CTranUcdos::ShowResult( CDC *pdc )
{
	char	sBuff[100] ;
	int		y	=32 ;
	
	wsprintf( sBuff , "输入法名:%s" , inputLibHead.sName ) ;
	pdc->TextOut( 0 , y , sBuff , strlen( sBuff ) ) ;
	y	+=16 ;
	wsprintf( sBuff , "功能键号:%c" , inputLibHead.nFunctionKey ) ;
	pdc->TextOut( 0 , y , sBuff , strlen( sBuff ) ) ;
	y	+=16 ;
	wsprintf( sBuff , "万能键:%c" , inputLibHead.nGodKey ) ;
	pdc->TextOut( 0 , y , sBuff , strlen( sBuff ) ) ;
	y	+=16 ;
	wsprintf( sBuff , "最大码长:%d" , inputLibHead.nMaxCodeLen ) ;
	pdc->TextOut( 0 , y , sBuff , strlen( sBuff ) ) ;
	y	+=16 ;
	wsprintf( sBuff , "总字节数:%lu 总行数:%lu 总词条数:%lu" , 
			inputLibHead.dwTotalBytes ,
			m_dwTotalLines , inputLibHead.dwTotalWords ) ;
	pdc->TextOut( 0 , y , sBuff , strlen( sBuff ) ) ;
}	

//得到一行
BOOL	CTranUcdos::GetOneLine( char *sLineBuff )
{
	if( m_dwSourcePoint >= m_dwSourceLen )	//完了
		return	0 ;

	int	nLineLen	=0 ;	//行长度
	for( ; m_dwSourcePoint < m_dwSourceLen ; m_dwSourcePoint++ )
	{
		if( m_dwSourcePoint < m_dwSourceLen-1 )
		{
			if( m_hpsSource[m_dwSourcePoint] == 0x0d &&
				m_hpsSource[m_dwSourcePoint+1] == 0x0a )	//行结束
			{
				m_dwSourcePoint	+=2 ;
				break ;
			}
		}
		sLineBuff[nLineLen++]	=m_hpsSource[m_dwSourcePoint] ;
	}
	
	sLineBuff[nLineLen]	='\0' ;
	return	1 ;
}	
					
//分析源库文件(指UCDOS输入法文本文件格式)
BOOL	CTranUcdos::Analysis( void )
{
	char	sLineBuff[201] ;			//行缓冲
//------------------------------------------------------------------//
	
	m_dwTotalLines	=0 ;
	m_dwSourcePoint	=0 ;			//源库指针指向库头
	while( 1 )
	{
		//得到一行
		if( !GetOneLine( sLineBuff ) )		//到达库尾
			return 1 ;

		m_dwTotalLines++ ;
		if( sLineBuff[0] == '\0' || sLineBuff[0] == ' ' )	//行结束或空格
			continue ;		//放弃该行
		
		if( sLineBuff[0] & 0x80 )		//是汉字
		{
			if( !AnalysisHead( sLineBuff ) )	//分析头
				return	0 ;
		}
		else		//头个字母是英文,说明这行是编码内容
		{
			inputLibHead.dwTotalWords++ ;	//词数增加
			if( !AnalysisContent( sLineBuff ) )	//分析编码项
				return 0 ;
		}
	}
	
	return	1 ;
}

BOOL	CTranUcdos::AnalysisContent( char *psLine )
{
	char	sTmpFile[13]	="a.tmp" ;		//临时文件名
	CFile	tmpFile ;
	
	sTmpFile[0]	=psLine[0] ;		//构造文件名
	//打开该文件
	if( !tmpFile.Open( sTmpFile , CFile::modeReadWrite|CFile::typeBinary ) )
	{
		//创建该文件
		if( !tmpFile.Open( sTmpFile , CFile::modeReadWrite|CFile::modeCreate|CFile::typeBinary ) )
		{
			AfxMessageBox( "创建文件失败" ) ;
			return	0 ;
		}
	}
	else
		//定位到文件尾
		tmpFile.SeekToEnd() ;
	
	INPUT_LIB_ITEM	item ;	//英文,汉字对照项
	item.nEnglishLen	=0 ;
	item.nChineseLen	=0 ;
	//去掉行首空格
	for( ; (*psLine) == ' ' ; psLine++ )
		;
	//得到英文编码
	for( ; (*psLine) && (*psLine)!=' ' ; psLine++ )
		item.sEnglish[item.nEnglishLen++]	=*psLine ;
	//去掉空格
	for( ; (*psLine) == ' ' ; psLine++ )
		;
	if( !(*psLine) )	//到达行尾
	{
		char	sBuff[50] ;
		wsprintf( sBuff , "第%d行只有编码,没有汉字" , m_dwTotalLines ) ;
		AfxMessageBox( sBuff ) ;
		return	0 ;
	}
	//得到汉字,直到行末
	for( ; *psLine ; )
	{
		if( (*psLine) == ' ' )
		{
			item.sChinese[item.nChineseLen++]	=' ' ;
			//去掉其后的所有空 格
			for( psLine++ ; (*psLine) && (*psLine)==' ' ; psLine ++ )
				;
		}
		else
			item.sChinese[item.nChineseLen++]	=*psLine++ ;
	}
	
	//写入文件
	tmpFile.Write( &item , sizeof( INPUT_LIB_ITEM ) ) ;
	//关闭文件
	tmpFile.Close() ;
	
	int	nBuffLen	=1+item.nEnglishLen+item.nChineseLen ;
	inputLibHead.dwTotalBytes	+=nBuffLen ;
	
	return	1 ;
}
		
//分析UCDOS输入法文本文件的头
BOOL	CTranUcdos::AnalysisHead( char *psLine )
{
	int			nFlag ;

	int			nNameLen ;				//等号后内容的长度
	char	*psNamePoint ;		//等号后内容的名字
	
	int			i ;
	
	nFlag	=0 ;
	if( !strncmp( "名称" , psLine , 4 ) )	//是输入法名称
	{
		nFlag	=1 ;
		psLine	+=4 ;
	}
	else if( !strncmp( "功能键号" , psLine , 8 ) )	
	{
		nFlag	=2 ;
		psLine	+=8 ;
	}
	else if( !strncmp( "码元表" , psLine , 6 ) )
	{
		nFlag	=3 ;
		psLine	+=6 ;
	}
	else if( !strncmp( "万能键" , psLine , 6 ) )
	{
		nFlag	=4 ;
		psLine	+=6 ;
	}
	else if( !strncmp( "最大码长" , psLine , 8 ) )
	{
		nFlag	=5 ;
		psLine	+=8 ;
	}
			
	if( !nFlag )	//不需要的东西
		return	1 ;
				
	//去掉空格和等号
	for( ; (*psLine) == ' ' || (*psLine) == '=' ; psLine++ )
		;
	//得到下一串内容(在碰到空格或行结束之前)
	psNamePoint	=psLine ;
	for( nNameLen=0 ; (*psLine) && (*psLine)!=' ' ; 
				nNameLen++,psLine++)
		;
	if( !nNameLen )
	{
		AfxMessageBox( "等号后没有东西" ) ;
		return	0 ;
	}
				
	switch( nFlag )
	{
		case	1:		//输入法名称
			if( nNameLen > MAX_NAME_LEN )	//太长
			{
				AfxMessageBox( "文件名太长" ) ;
				return	0 ;
			}
			//得到文件名
			strncpy( inputLibHead.sName , psNamePoint , nNameLen ) ;
			inputLibHead.sName[nNameLen]	='\0' ;
			break ;
		case	2:	//功能键号
			if( nNameLen > 1 )
			{
				AfxMessageBox( "功能键号不是个位数" ) ;
				return	0 ;
			}
			inputLibHead.nFunctionKey	=(int)(*psNamePoint) ;
			break ;
		case	3:	//码元表
			if( nNameLen > CODE_CELL_NUM )
			{
				AfxMessageBox( "码元太多了" ) ;
				return	0 ;
			}

			for( i=0 ; i<nNameLen ; i++ )	//得到码元
			{
				if( psNamePoint[i] < 33 || psNamePoint[i] > 126 )
				{
					AfxMessageBox( "码元不合法" ) ;
					return	0 ;
				}
				//设上标记
				inputLibHead.sCodeCells[psNamePoint[i]-33]	=1 ;
			}
			break ;
		case	4:	//万能键
			if( nNameLen > 1 )
			{
				AfxMessageBox( "万能键不是一个键" ) ;
				return	0 ;
			}
			inputLibHead.nGodKey	=(int)(*psNamePoint) ;
			break ;
		case	5:		//最大码长
			psNamePoint[nNameLen]	='\0' ;
			i	=atoi( psNamePoint ) ;	//将字符串转换成整数
			if( i<=0 || i>MAX_CODE_LEN )
			{
				AfxMessageBox( "最大码长不对" ) ;
				return	0 ;
			}
			inputLibHead.nMaxCodeLen	=i ;
			break ;
	}
	
	return	1 ;
}

#ifdef __cplusplus
extern "C" {
#endif

BOOL __export FAR PASCAL	TranslateUcdos( LPCSTR pathName )
{
	return	OTranUcdos.TranslateUcdos( pathName ) ;
}

#ifdef __cplusplus
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -