This program was compiled successfully in Turbo C 2.0 on an X86 microcomputer equipped with a VGA display card, and runs well in both Chinese and Western text modes.
#include
#include
#include
#include
#include
#include
#include
#define EnglistWordNum 20 /*maximum number of characters in an English word*/
#define WORD unsigned int
#define BYTE unsigned char
#define ENGLISH 1 /*English text mode*/
#define CHINESE 2 /*Chinese text mode*/
#define SHOW_DICT_UP 1 /*position where the "screen dictionary" is shown at the top of the screen*/
#define DICT_LINE 7 /*number of lines occupied by the "screen dictionary"*/
#define SHOW_DICT_DOWN (25-DICT_LINE) /*line position for display at the bottom*/
#define SHOW_DICT_ENGLISHWORD_X 30 /*column coordinate where the English word is displayed*/
#define COLOR WHITE /*foreground color of the "screen dictionary"*/
#define BKCOLOR BLUE /*background color of the "screen dictionary"*/
#define QU 192 /*starting position of the left Chinese character half*/
#define WEI 128 /*starting position of the right Chinese character half*/
#define HZK16 "C:\\ucdos\\hzk16" /*Chinese font file*/
#define EC "c:\\ucdos\\drv\\EC.imd" /*English-Chinese input method dictionary file*/
#define BEEP() printf("\7"

; /*beep*/
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 /*error codes*/
{ OK, /*no error*/
HzkFileNotOpen, /*Chinese font file cannot be opened */
FileNotOpen, /*code file cannot be opened */
MallocError, /*memory allocation error */
NotImdFile, /*not an IMD file*/
};
typedef struct IMD
{ BYTE ImdId; /*IMD file identifier*/
BYTE space1; /*reserved*/
BYTE CodingName; /*code name*/
BYTE HotKey; /*function key number*/
BYTE CodeTable; /*code element table*/
BYTE CodeTableSize; /*actual code size*/
BYTE OmniptentKey; /*universal code length*/
BYTE MaxCodeLenght; /*maximum code length*/
BYTE AutoChoiceInput; /*whether auto input is enabled*/
BYTE RunSearch; /*whether fuzzy search is performed*/
BYTE UseDefineWord; /*whether user-defined phrases are used*/
BYTE DefineWordsMode; /*user-defined phrase scheme*/
BYTE space2; /*reserved*/
BYTE PreWordCodeLength; /*maximum code length for single-character lookup*/
BYTE RecodeId; /*duplicate-code flag*/
WORD SearchWordNumber; /*number of single-character lookup codes*/
WORD InderCodeSize; /*length of single-character lookup codes*/
WORD CwordNumber; /*number of Chinese characters*/
WORD InderTableOffset; /*start address of the lookup index table*/
WORD InderTableNumber; /*number of index tables*/
BYTE space3; /*reserved*/
} ;
char UserFont; /*bitmap data of user-defined extended ASCII characters*/
int DictStatus=DOWN; /*current display position status of the dictionary*/
char ShowMode; /*current text mode*/
int first=1; /*whether to display the "screen dictionary" border*/
FILE *LibFp; /*Chinese font file*/
FILE *ImdFp; /*code file pointer*/
struct IMD *ImdHeadMsg; /*IMD file header info*/
BYTE *InderTable; /*IMD lookup index table pointer*/
int line=SHOW_DICT_DOWN; /*current line coordinate where the dictionary is displayed*/
int LoadIMD(BYTE *file);/*load the Chinese input method IMD file*/
void RestoreScreen(); /*restore screen content*/
void SaveScreen(); /*save screen content*/
void PutChar(char c,int x,int y,int color,int bkcolor);
/*display character C in Western text mode*/
void LoadDefaultFontToBuf(); /*load the default VGA font into memory*/
void SetWordFont(unsigned char a,unsigned char b);
/*set the currently used working fonts*/
void LoadUserFontToVGA(); /*load the user font into VGA*/
void LoadDefaultFont(int n); /*load the default font into VGA plane 2*/
void LoadCwordModeToUserFont(char *buf,int n);
void RemoveIMD(); /*unload the input method loaded by the LoadIMD function*/
void ShowMsg();
void GetWord(BYTE *,BYTE *,BYTE *);
int GetEnglishCword(BYTE *buf,BYTE *CodeBuf);
void ShowDictMsg();
char EnglishWord="Screen EC Dictionary"; /*English word*/
char CwordMsg="《Screen English-Chinese Dictionary》 Design: Hubei Province Shui Shi"; /*Chinese message*/
void GetCwordMode(unsigned char *s, unsigned char *mode)
/* get Chinese character bitmap information*/
{ 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)
/* write a Chinese character bitmap into the user-defined font */
{ int i;
for(i=0;i0xa0)
{ GetCwordMode(s,buf);
LoadCwordModeToUserFont(buf,i);
i++; s+=2;
}
else s++;
}
LoadUserFontToVGA(FP_SEG(UserFont),FP_OFF(UserFont),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)
{ /*display character*/
pokeb(0xb800,2*x+y*160,c); /*write character*/
color=((bkcolor&0xf)<<4)|(color&0x7);
/*upper four bits are background color, lower three bits are foreground color, when B3=1, character set A is used, otherwise character set B*/
color|=0x8;
pokeb(0xb800,2*x+y*160+1,color);
}
void LoadDefaultFont()
{ int i,j;
_AX=0x1104; /*load VGA standard font*/
_BL=0;
geninterrupt(0x10);
}
void LoadDefaultFontToBuf()
{ int bp;
bp=_BP; /*save original BP value*/
_AX=0x1130; /*AX=1130H returns font info*/
_BH=6; /*BH=6 requests the address of the ROM 8*16 VGA standard font*/
geninterrupt(0x10);
/*returns ES:BP=segment address

ffset address of the character set */
/*COPY the VGA standard 8*16 dot-matrix font information into memory*/
movedata(_ES, _BP,FP_SEG(&UserFont),FP_OFF(&UserFont),256*16);
_BP=bp; /*restore original BP value*/
}
/********************************************
Function: load user character set into plane 2
Input parameters:seg segment address of the user character set
off offset address of the user character set
n area number in plane 2
*********************************************/
void LoadUserFontToVGA(int seg,int off,int n)
{ int bp;
bp=_BP;
_AX=seg; /*segment address of user characters*/
_ES=_AX;
_AX=0x1110; /*AX=1110 load user-defined character set*/
_BH=16; /*number of bytes of bitmap data per character*/
_BL=n; /*area number in plane 2 (VGA 0-7;EGA:0-3) */
_DX=0; /*offset within the area in plane 2*/
_CX=256; /*number of characters to load*/
_BP=off; /*offset of user characters*/
geninterrupt(0x10);
_BP=bp;
}
void SetWordFont(unsigned char a,unsigned char b)
/*Function: set working character sets
Input parameters:a area number of character set A
b area number of character set B*/
{ b=(b&7)<< 2; /*VGA has at most 8 areas*/
a=(a&3)|((a<<3)&0x10);
b=(b&12)|((b<<2)&0x20);
a|=b;
_BL=a;
/*b4,b1,b0 =area number of font A in plane 2
b5,b3,b2 =area number of font B in plane 2*/
_AX=0x1103; /*select working characters*/
geninterrupt(0x10);
}
void SaveScreen()
{movedata(0xb800,0,0xb800,160*25,160*25);}
void RestoreScreen()
{movedata(0xb800,160*25,0xb800,0,160*25);}
/*Function: get the English word at screen coordinates (x,y)
Input parameters:x,y screen coordinates
buf location where the screen word is saved*/
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)
/*Function: edit a string
Input parameters: x,y display coordinates
buf the string to modify
max maximum number
Output parameter:user keypress */
{ char s;
char format;
int key;
int len;
len=strlen(buf);
gotoxy(x,y); /*display the string at the coordinates*/
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=0;
}
else BEEP();
break;
default:
if (len=' ' && keyImdId,"UCDOS IMD FILE\x1a"

)
{/*compare whether it is UCDOS IMD FILE*/
free(ImdHeadMsg);/*release the memory allocated for storing the IMD file header info*/
fclose(ImdFp);
return(NotImdFile);
}
size=ImdHeadMsg->InderTableNumber*3; /*calculate index table size*/
InderTable=(BYTE *)malloc(size+1);/*allocate memory for index content*/
if (InderTable==NULL)
{ free(ImdHeadMsg);
fclose(ImdFp);
return(MallocError);
}
fseek(ImdFp,0x80+ImdHeadMsg->InderTableOffset,SEEK_SET);
fread(&InderTable,size,1,ImdFp);
/*read the index content into the index list*/
size=ImdHeadMsg->InderTableOffset+
ImdHeadMsg->InderTableNumber*3+0x80;
memmove(InderTable,&size,3);
return(OK); /*loaded successfully*/
}