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; 
            } 
        } 
    }