此程序在Turbo C 2.0中,配的VGA显示卡的X86微机上编译通过,在中、西文本两种方式下运行良好。
#include
#include
#include
#include
#include
#include
#include
#define EnglistWordNum 20 /*英语单词最大字符数*/
#define WORD unsigned int
#define BYTE unsigned char
#define ENGLISH 1 /*英文文本模式*/
#define CHINESE 2 /*中文文本模式*/
#define SHOW_DICT_UP 1 /*"屏幕字典"显示屏幕上方的位置*/
#define DICT_LINE 7 /*"屏幕字典"占用的行数*/
#define SHOW_DICT_DOWN (25-DICT_LINE) /*下方显示的行位置*/
#define SHOW_DICT_ENGLISHWORD_X 30 /*英语单词显示的列坐标*/
#define COLOR WHITE /*"屏幕字典"前景色*/
#define BKCOLOR BLUE /*"屏幕字典背景色*/
#define QU 192 /*左边汉字开始位置*/
#define WEI 128 /*右边汉字开始位置*/
#define HZK16 "C:\\ucdos\\hzk16" /*汉字库文件*/
#define EC "c:\\ucdos\\drv\\EC.imd" /*英中输入法字典文件*/
#define BEEP() printf("\7"

; /*响铃*/
enum
{ ESC = 0x011b,
END = 0x4f00,
TAB = 0x0f09,
HOME = 0x4700,
PageUp = 0x4900,
PageDown = 0x5100,
Ctrl_Home = 0x7700,
Ctrl_End = 0x7500,
BreakSpace =0xe08,
LEFT = 0x4b00,
RIGHT = 0x4d00,
ENTER = 0x1c0d,
UP = 0x4800,
DOWN = 0x5000,
} ;
enum InputMethodErrorCode /*错误代码*/
{ OK, /*无错误*/
HzkFileNotOpen, /*汉字库不能打开 */
FileNotOpen, /*编码文件不能打开 */
MallocError, /*内存分配错误 */
NotImdFile, /*不是IMD文件*/
};
typedef struct IMD
{ BYTE ImdId[0x10]; /*IMD文件标志*/
BYTE space1[0x10]; /*保留*/
BYTE CodingName[9]; /*编码名称*/
BYTE HotKey; /*功能键号*/
BYTE CodeTable[0x41]; /*码元表*/
BYTE CodeTableSize; /*实际编码大小*/
BYTE OmniptentKey; /*万能码长*/
BYTE MaxCodeLenght; /*最大码长*/
BYTE AutoChoiceInput; /*是否自动输入*/
BYTE RunSearch; /*是否执行模糊搜索*/
BYTE UseDefineWord; /*是否使用自定义词组*/
BYTE DefineWordsMode; /*自定义词组方案*/
BYTE space2; /*保留*/
BYTE PreWordCodeLength; /*单字查询编码最大长度*/
BYTE RecodeId; /*重码标志*/
WORD SearchWordNumber; /*单字查询编码个数*/
WORD InderCodeSize; /*单字查询编码长度*/
WORD CwordNumber; /*汉字个数*/
WORD InderTableOffset; /*查询索引表首地址*/
WORD InderTableNumber; /*索引表数目*/
BYTE space3; /*保留*/
} ;
char UserFont[256][16]; /*用户自定义扩展ASCII字模数据*/
int DictStatus=DOWN; /*当前字典显示的位置情况*/
char ShowMode; /*当前处于文本模式*/
int first=1; /*是否显示"屏幕字典"边框*/
FILE *LibFp; /*汉字库文件*/
FILE *ImdFp; /*编码文件指针*/
struct IMD *ImdHeadMsg; /*IMD文件头部信息*/
BYTE *InderTable; /*IMD查询索引表指针*/
int line=SHOW_DICT_DOWN; /*当前字字典显示的行坐标*/
int LoadIMD(BYTE *file);/*装入汉字输入法IMD文件*/
void RestoreScreen(); /*恢复屏幕内容*/
void SaveScreen(); /*保存屏幕内容*/
void PutChar(char c,int x,int y,int color,int bkcolor);
/*在西方文本方式下显示一字符C*/
void LoadDefaultFontToBuf(); /*装入VGA默认的字库到内存*/
void SetWordFont(unsigned char a,unsigned char b);
/*设置当前选用的工作字库*/
void LoadUserFontToVGA(); /*装入用户字库到VGA*/
void LoadDefaultFont(int n); /*装入默认的字库到VGA平面2*/
void LoadCwordModeToUserFont(char *buf,int n);
void RemoveIMD(); /*卸由LoadIMD函数装入的输入方法*/
void ShowMsg();
void GetWord(BYTE *,BYTE *,BYTE *);
int GetEnglishCword(BYTE *buf,BYTE *CodeBuf);
void ShowDictMsg();
char EnglishWord[30]="Screen EC Dictionary"; /*英语单词*/
char CwordMsg[80]="《屏幕英汉字典》 设计:湖北省 水师"; /*汉语信息*/
void GetCwordMode(unsigned char *s, unsigned char *mode)
/* 取汉字字模信息*/
{ long offset;
offset=((*s-0xa1)*94L+(*(s+1)-0xa1))*32L;
fseek(LibFp,offset,SEEK_SET);
fread(mode,1,32,LibFp);
}
void LoadCwordModeToUserFont(char *buf,int n)
/* 将一汉字字模写入用户定义的字库中 */
{ int i;
for(i=0;i0xa0)
{ GetCwordMode(s,buf);
LoadCwordModeToUserFont(buf,i);
i++; s+=2;
}
else s++;
}
LoadUserFontToVGA(FP_SEG(UserFont[0]),FP_OFF(UserFont[0]),1);
SetWordFont(0,1);
for(i=0,s=olds;*s

if (*s>0x80)
{PutChar(QU+i,x++,y,color,bkcolor);
PutChar(WEI+i,x++,y,color,bkcolor);
i++;s+=2;
}
else {gotoxy(1+x++,y+1);putch(*s++);}
}
void PutChar(char c,int x,int y,int color,int bkcolor)
{ /*显示的字符*/
pokeb(0xb800,2*x+y*160,c); /*写字符*/
color=((bkcolor&0xf)<<4)|(color&0x7);
/*前四位为背景色,后三位为前景色,B3=1时,用字符集A,否则用字符集B*/
color|=0x8;
pokeb(0xb800,2*x+y*160+1,color);
}
void LoadDefaultFont()
{ int i,j;
_AX=0x1104; /*装入VGA标准字库*/
_BL=0;
geninterrupt(0x10);
}
void LoadDefaultFontToBuf()
{ int bp;
bp=_BP; /*保存原BP值*/
_AX=0x1130; /*AX=1130H 返回字库信息*/
_BH=6; /*BH=6 请求返回ROM 8*16VGA标准字库的地址*/
geninterrupt(0x10);
/*返回 ES:BP=字符集的段地址:偏移地址 */
/*将VGA标准8*16点阵字库信息COPY到内存中*/
movedata(_ES, _BP,FP_SEG(&UserFont[0][0]),FP_OFF(&UserFont[0][0]),256*16);
_BP=bp; /*恢复原BP值*/
}
/********************************************
函数作用:装入用户字符集到位平面2中
入口参数:seg 用户字符集的段址
off 用户字符集的偏移地址
n 位平面2中的区号
*********************************************/
void LoadUserFontToVGA(int seg,int off,int n)
{ int bp;
bp=_BP;
_AX=seg; /*用户字符段地址*/
_ES=_AX;
_AX=0x1110; /*AX=1110 装入用户定义的字符集*/
_BH=16; /*每个字符字模数据字节数*/
_BL=n; /*位平面2中的区号(VGA 0-7;EGA:0-3) */
_DX=0; /*位平面2中区内偏移量*/
_CX=256; /*需装入的字符个数*/
_BP=off; /*用户字符的偏移地址*/
geninterrupt(0x10);
_BP=bp;
}
void SetWordFont(unsigned char a,unsigned char b)
/*函数作用:设置工作字符集
入口参数:a 字符集A的区号
b 字符集B的区号*/
{ b=(b&7)<< 2; /*VGA最多8个区*/
a=(a&3)|((a<<3)&0x10);
b=(b&12)|((b<<2)&0x20);
a|=b;
_BL=a;
/*b4,b1,b0 =字库A在位平面2 中的区号
b5,b3,b2 =字库B在位平面2 中的区号*/
_AX=0x1103; /*选择工作字符*/
geninterrupt(0x10);
}
void SaveScreen()
{movedata(0xb800,0,0xb800,160*25,160*25);}
void RestoreScreen()
{movedata(0xb800,160*25,0xb800,0,160*25);}
/*函数作用:获取屏幕坐标(x,y)处的英语单词
入口参数:x,y 屏幕坐标
buf 屏幕单词保存处*/
void GetScreenWord(int x,int y,char *buf)
{ int i; char c;
c=tolower(peekb(0xb800,y*160+2*x));
if (c='z') { *buf=0;return;}
if (x>0)
{ do{ c=tolower(peekb(0xb800,y*160+2*x));
if( c'z') { x++;break;}
x--;
}while(x>0);
}
for(c=tolower(peekb(0xb800,y*160+2*x));c='a'

{*buf++=c;x++;
c=tolower(peekb(0xb800,y*160+2*x));
}
*buf=0;
}
int EditString(char *buf,int x,int y,int max)
/*函数作用: 编辑字符串
入口参数: x,y 显示的坐标
buf 欲修改的字符串
max 最大个数
出口参数:用户按键 */
{ char s[256];
char format[10];
int key;
int len;
len=strlen(buf);
gotoxy(x,y); /*在坐标处显示字符串*/
strcpy(s,buf);
printf(s);
while(1)
{ key=bioskey(0);
switch(key)
{ case ESC:
case TAB: return(key);
case ENTER: strcpy(buf,s);
return(ENTER);
case BreakSpace:
if (len>0)
{ gotoxy(wherex()-1,wherey());
putchar(' ');
gotoxy(wherex()-1,wherey());
len--; s[len]=0;
}
else BEEP();
break;
default:
if (len=' ' && keyImdId,"UCDOS IMD FILE\x1a"

)
{/*比较是否为UCDOS IMD FIlE*/
free(ImdHeadMsg);/*释放为存放IMD文件头部信息而分配的内存*/
fclose(ImdFp);
return(NotImdFile);
}
size=ImdHeadMsg->InderTableNumber*3; /*计算索引表大小*/
InderTable=(BYTE *)malloc(size+1);/*为索引内容分配内存*/
if (InderTable==NULL)
{ free(ImdHeadMsg);
fclose(ImdFp);
return(MallocError);
}
fseek(ImdFp,0x80+ImdHeadMsg->InderTableOffset,SEEK_SET);
fread(&InderTable[3],size,1,ImdFp);
/*将索引内容读入索引列表中*/
size=ImdHeadMsg->InderTableOffset+
ImdHeadMsg->InderTableNumber*3+0x80;
memmove(InderTable,&size,3);
return(OK); /*挂接成功*/
}