www.pudn.com > cwin.rar > CODEPUB.C
/*-----------------------------------------------------------
汉字输入模块公用变量及函数
-----------------------------------------------------------*/
#include
#include
#include
#define BUFFER_SIZE 512
/*-- 重码提示符的字模点阵 ---------------------------------*/
unsigned char _ArrowFont[]=
{
0x01,0xFF81,0xFF80,0x07,0xFF81,
0xFFE0,0x1F,0xFFFF,0xFFF8,0x1F,0xFFFF,0xFFF8,0x07,
0xFF81,0xFFE0,0x01,0xFF81,0xFF80,
0x00,0xFFC0,0x00,0x03,0xFFC0,0x00,
0x0F,0xFFFF,0xFFF0,0x0F,0xFFFF,0xFFF0,0x03,0xFFC0,0x00,
0x00,0xFFC0,0x00,
0x00,0x03,0x00,0x00,0x03,0xFFC0,
0x0F,0xFFFF,0xFFF0,0x0F,0xFFFF,0xFFF0,0x00,0x03,0xFFC0,
0x00,0x03,0x00
};
/*-- 全局变量说明 -----------------------------------------*/
char _CodeBuffer[BUFFER_SIZE]; /* 输入码表缓冲区 */
char _CodePrompt[41]; /* 代码提示缓冲区 */
char _DupPrompt [120]; /* 重码缓冲区 */
/*-- 公用函数说明 -----------------------------------------*/
int _Cdecl _SrchCode (unsigned char *front,char *inputcode,int maxcodes,int wildchar);
int _Cdecl _NextDup (unsigned char *buff,unsigned char *code,int len,int wild);
void _Cdecl _DispInputCode(int i,int len);
unsigned _Cdecl _OutCode (unsigned h);
char *_Cdecl _GetCodeBlock(long offset,MODE_TYPE *mode);
unsigned char *_Cdecl _GetString(unsigned char *ptr,unsigned char *tmpline);
unsigned _Cdecl _SearchCZ(char *code);
/*-----------------------------------------------------------
函数 _SrchCode : 查表
-----------------------------------------------------------*/
int _Cdecl _SrchCode(front,inputcode,maxcodes,wildchar)
unsigned char *front;
char *inputcode;
int maxcodes;
int wildchar;
{
unsigned char *p = front;
char tmpcode[13];
int i;
while(*p)
{
if(wildchar)
{
memcpy(tmpcode,p,maxcodes);
tmpcode[maxcodes] = 0;
for(i=0;i0xa0 || *p=='\r' || *p=='\n')
p++;
if(*p == 0)
break;
}
return strlen(front)+1;
}
/*-----------------------------------------------------------
函数 _GetString : 从码表中取一串
-----------------------------------------------------------*/
unsigned char *_Cdecl _GetString(ptr,tmpline)
unsigned char *ptr,*tmpline;
{
while(ishan(ptr))
{
*tmpline++ = *ptr++;
*tmpline++ = *ptr++;
}
*tmpline = 0;
if(*ptr=='\r')
ptr+=2;
return ptr;
}
/*-----------------------------------------------------------
函数 _NextDup : 取下一重码
-----------------------------------------------------------*/
int _Cdecl _NextDup(buff,code,len,wild)
unsigned char *buff;
unsigned char *code;
int len;
int wild;
{
int i;
for(i=0;iwherecodes)
{
case DSK:
fseek(mode->codefile,offset,SEEK_SET);
len = fread(_CodeBuffer,1,BUFFER_SIZE,mode->codefile);
break;
case XMS:
_Emb.len = BUFFER_SIZE;
_Emb.sour_han = mode->handle;
_Emb.sour_off = offset;
_Emb.dest_han = 0;
_Emb.dest_off = FP_SEG(_CodeBuffer);
_Emb.dest_off <<= 16;
_Emb.dest_off += FP_OFF(_CodeBuffer);
_MoveDataXMS();
len = mode->filelen-offset;
len = len>BUFFER_SIZE?BUFFER_SIZE:len;
break;
case EMM:
addr = FP_SEG(_CodeBuffer);
addr = (addr<<4)+FP_OFF(_CodeBuffer);
_SetDestAddr(addr,BUFFER_SIZE);
addr = mode->EMM_addr+offset;
_SetSourAddr(addr,BUFFER_SIZE);
_MoveDataEMM(BUFFER_SIZE);
len = mode->filelen-offset;
len = len>BUFFER_SIZE?BUFFER_SIZE:len;
break;
}
ptr = _CodeBuffer+len-1;
while((*ptr)>0xa0 || *ptr=='\r' || *ptr=='\n')
ptr--;
while(strchr(mode->codeset,*ptr) || *ptr==' ')
ptr--;
*(ptr-1) = 0;
ptr = _CodeBuffer;
while(strchr(mode->codeset,*(ptr+i)) || *(ptr+i)==' ')
i++;
if(imaxcodes)
{
while(strchr(mode->codeset,*ptr) || *ptr==' ')
ptr++;
while((*ptr)>0xa0 || *ptr=='\r' || *ptr=='\n')
ptr++;
}
return ptr;
}
/*-----------------------------------------------------------
函数 _OutCode : 输出代码
-----------------------------------------------------------*/
unsigned _Cdecl _OutCode(unsigned h)
{
char tmpstr[17];
char *ptr,*qtr;
ptr = strchr(_CodePrompt,h)+2;
ptr = takehan(ptr,&h);
qtr = tmpstr;
while(ishan(ptr))
{
*qtr++ = *ptr++;
*qtr++ = *ptr++;
}
*qtr = 0;
if(strlen(tmpstr))
ungetstr(tmpstr);
return h;
}
/*-----------------------------------------------------------
函数 _DispInputCode : 显示输入码
-----------------------------------------------------------*/
void _DispInputCode(int i,int len)
{
char tmpline[17];
memcpy(tmpline,_DupPrompt+i*len,len);
tmpline[len] = 0;
putxys(16,_PromptLine+7,_PmtColor,_PmtBk,tmpline);
}
/*-----------------------------------------------------------
函数 _SearchCZ : 查找词组
-----------------------------------------------------------*/
unsigned _Cdecl _SearchCZ(code)
char *code;
{
unsigned h;
unsigned char *front = NULL;
unsigned char *p = NULL;
unsigned char *q = NULL;
int pos = 0;
int maxcodes = _Mode[_HanMode].maxcodes; /* 输入码最大长度 */
int wildchar = _Mode[_HanMode].wildchar; /* 万能替换键码 */
char *codeset = _Mode[_HanMode].codeset; /* 输入法用键集合 */
FILE *codefile = _Mode[_HanMode].codefile; /* 输入法码表文件 */
int forward = NO;
int pageno = 0;
int havewild = (int)strchr(code,wildchar);
long low,high,mid;
static int i = 0;
char tmpline[17];
char tmpstr[17];
/*---- 如果输入码的第一键即为万能替换键 ---------------*/
if(code[0] == wildchar)
{
mid = _Mode[_HanMode].filefront;
front = _GetCodeBlock(mid,_Mode+_HanMode);
pos = 0;
goto Search_Success;
}
/*---- 用二分法在码表中查找输入码 ---------------------*/
low = _Mode[_HanMode].filefront;
high = _Mode[_HanMode].filelen;
while(high > low)
{
if(high <= BUFFER_SIZE)
low = _Mode[_HanMode].filefront;
if(high-low <= BUFFER_SIZE)
mid = low;
else
mid = (high+low-BUFFER_SIZE)/2;
front = _GetCodeBlock(mid,_Mode+_HanMode);
pos = _SrchCode(front,code,maxcodes,havewild?wildchar:0);
if(pos < 0)
high = mid-1;
else if(pos > strlen(front))
low = mid+BUFFER_SIZE-maxcodes-16;
else
goto Search_Success;
}
/*---- 查找失败 ---------------------------------------*/
_ClearPrompt(1);
putch(Beep);
return 0;
/*---- 查找成功 ---------------------------------------*/
Search_Success:
/*---- 找到重码的第一个 -------------------------------*/
while(1)
{
p = front+pos-1;
while(p>front && !strchr(codeset,*p))
p--;
if(p_Mode[_HanMode].filefront)
{
mid -= strlen(front);
if(mid<_Mode[_HanMode].filefront)
mid = _Mode[_HanMode].filefront;
front = _GetCodeBlock(mid,_Mode+_HanMode);
pos = _SrchCode(front,code,maxcodes,havewild?wildchar:0);
if(pos > strlen(front))
{
mid += strlen(front);
fseek(codefile,mid,SEEK_SET);
front = _GetCodeBlock(mid,_Mode+_HanMode);
pos = _SrchCode(front,code,maxcodes,havewild?wildchar:0);
break;
}
else if(mid > _Mode[_HanMode].filefront)
continue;
else
break;
}
else
break;
}
/*---- 在提示行上显示重码序列并选择 -------------------*/
q = front+pos+maxcodes;
while(1)
{
p = _CodePrompt;
i = 0;
Loop:
if(havewild)
memcpy(_DupPrompt+i*maxcodes,q-maxcodes,maxcodes);
q = _GetString(q,tmpline);
if(strlen(tmpline) < (40-(p-_CodePrompt)))
{
sprintf(p,"%d:%s",i==9?0:i+1,tmpline);
p += strlen(tmpline)+2;
i++;
}
else
{
forward = YES;
goto Display;
}
NextPage:
if(strlen(q) == 0)
{
mid += strlen(front);
if(mid>_Mode[_HanMode].filelen)
mid = _Mode[_HanMode].filelen-BUFFER_SIZE;
front = _GetCodeBlock(mid,_Mode+_HanMode);
q = front;
}
if(_NextDup(q,code,maxcodes,wildchar))
{
q += maxcodes;
goto Loop;
}
/*---- 显示重码序列 -------------------------------*/
Display:
_ClearPrompt(2);
outxys(29,_PromptLine+7,_PmtColor,_CodePrompt);
if(pageno && forward)
_DrawF(70*8,_PromptLine+13,3,6,_PmtColor,_ArrowFont);
else if(pageno)
_DrawF(70*8,_PromptLine+13,3,6,_PmtColor,_ArrowFont+18);
else if(forward)
_DrawF(70*8,_PromptLine+13,3,6,_PmtColor,_ArrowFont+36);
/*---- 如果没有重码则直接返回结果 -----------------*/
if(i == 1)
{
if(havewild)
_DispInputCode(0,maxcodes);
p = takehan(tmpline,&h);
if(strlen(p))
ungetstr(p);
return h;
}
/*---- 在重码中选择 -------------------------------*/
putch(Beep);
AcceptSelect:
h = geth();
/*---- 如果输入的是数字键则选择 -------------------*/
if(h>='1' && h<= i+'1' || i==9 && h=='0')
{
if(havewild)
_DispInputCode(h=='0'?9:h-'1',maxcodes);
p = strchr(_CodePrompt,h)+2;
p = takehan(p,&h);
q = tmpstr;
while(ishan(p))
{
*q++=*p++;
*q++=*p++;
}
*q = 0;
if(strlen(tmpstr))
ungetstr(tmpstr);
return h;
}
/*---- 如果是作废键则退出 -------------------------*/
else if(h == KEY_ENTER)
{
_ClearPrompt(1);
return 0;
}
/*---- 如果是向前翻页键 ---------------------------*/
else if( pageno && h=='-')
{
unsigned char *r = tmpline;
int len = 0,j = 0;
q = _CodePrompt+2;
while(*q!='2')
*r++ = *q++;
*r = 0;
if((q = strstr(front,tmpline))==0)
{
mid -= strlen(front);
if(mid<_Mode[_HanMode].filefront)
mid = _Mode[_HanMode].filefront;
front = _GetCodeBlock(mid,_Mode+_HanMode);
q = strstr(front,tmpline);
}
q--;
do
{
q -= maxcodes;
if(q <= front)
{
mid -= strlen(front);
if(mid<_Mode[_HanMode].filefront)
mid = _Mode[_HanMode].filefront;
front = _GetCodeBlock(mid,_Mode+_HanMode);
q = front+strlen(front)-1;
}
j = 0;
while(*q>0xa0 || *q=='\r' || *q=='\n')
{
j++;
q--;
}
if(_NextDup(q-3,code,maxcodes,wildchar))
len += j;
else
{
q++;
while(ishan(q) || *q=='\r')
q+=2;
while(strchr(codeset,*q) || *q==' ')
q++;
q--;
break;
}
}while(len<40);
q++;
if(len>40)
{
while(ishan(q) || *q=='\r')
q+=2;
q += maxcodes;
}
pageno--;
continue;
}
/*---- 如果是向后翻页键 ---------------------------*/
else if(forward && h == '=' && forward)
{
if(havewild)
memcpy(_DupPrompt,_DupPrompt+i*maxcodes,maxcodes);
i = 0;
p = _CodePrompt;
sprintf(p,"%d:%s",i==9?0:i+1,tmpline);
p += strlen(tmpline)+2;
i++;
forward = NO;
pageno++;
goto NextPage;
}
/*---- 其他键不起作用 -----------------------------*/
else
{
putch(Beep);
goto AcceptSelect;
}
}
}