📄 ime.cpp
字号:
#include "graphics.h"
int scancode_table[] = {
0x1e, // KEY_A
0x30, // KEY_B
0x2e, // KEY_C
0x20, // KEY_D
0x12, // KEY_E
0x21, // KEY_F
0x22, // KEY_G
0x23, // KEY_H
0x17, // KEY_I
0x24, // KEY_J
0x25, // KEY_K
0x26, // KEY_L
0x32, // KEY_M
0x31, // KEY_N
0x18, // KEY_O
0x19, // KEY_P
0x10, // KEY_Q
0x13, // KEY_R
0x1f, // KEY_S
0x14, // KEY_T
0x16, // KEY_U
0x2f, // KEY_V
0x11, // KEY_W
0x2d, // KEY_X
0x15, // KEY_Y
0x2c, // KEY_Z
};
LIST *ime_list = create_list(); // 输入法列表
CODE_TYPE *entry_ime = NULL; // 当前输入法
LIST *entry_hz = NULL;
// 安装输入法
BOOL install_ime(char *filename)
{
CODE_TYPE *temp = new CODE_TYPE;
if (temp == NULL)
return FALSE;
FILE *fp;
fp = fopen(filename, "rb");
if (fp == NULL)
return FALSE;
// 获取码表信息
fscanf(fp, "名称 = %s\n", temp->name);
fscanf(fp, "码元表 = %s\n", temp->key);
fscanf(fp, "万能键 = %c\n", &temp->hotkey);
fscanf(fp, "最大码长 = %d\n", &temp->len);
char autosel;
fscanf(fp, "是否自动选择输入 = %c", &autosel);
if (autosel == 'y' || autosel == 'Y')
temp->autosel = TRUE;
else
temp->autosel = FALSE;
temp->mb = create_list();
fscanf(fp, "\n");
// 装入码表
char buffer[1024];
MB *temp_mb;
BOOL first = TRUE;
while(TRUE)
{
fscanf(fp, "%s", buffer);
if (*buffer >= 'a' && *buffer <= 'z')
{
// 为汉字编码
temp_mb = new MB;
if (temp_mb == NULL)
return FALSE;
add_point(temp->mb, temp_mb);
temp_mb->code = new char [strlen(buffer) + 1];
if (temp_mb->code == NULL)
return FALSE;
strcpy(temp_mb->code, buffer);
first = TRUE;
}
else
{
if (strcmp(buffer, "[END]") == 0)
break;
else
if (*buffer == '\n')
continue;
else
{
// 为汉字字符串
if (first)
{
temp_mb->hz = create_list();
first = FALSE;
}
HZ *temp_hz = new HZ;
if (temp_hz == NULL)
return FALSE;
temp_hz->hz = new char [strlen(buffer) + 1];
if (temp_hz->hz == NULL)
return FALSE;
strcpy(temp_hz->hz, buffer);
add_point(temp_mb->hz, temp_hz);
}
}
}
add_point(ime_list, temp);
fclose(fp);
return TRUE;
}
// 激活输入法
BOOL active_ime(int index)
{
if (index <= 0)
{
// index<=0时输入英文
entry_ime = NULL;
}
else
{
seek_to_first(ime_list);
for (int i = 0; i < index - 1; i++)
{
if (ime_list->entry->data == NULL)
return FALSE;
seek_to_next(ime_list);
}
entry_ime = (CODE_TYPE *)(ime_list->entry->data);
}
entry_hz = NULL;
return TRUE;
}
// 给出一个编码,返回当前码表对应的汉字字符串链表
void get_hzlist(char *code)
{
if (entry_ime == NULL)
return;
seek_to_first(entry_ime->mb);
MB *mb;
while(entry_ime->mb->entry != NULL)
{
mb = (MB *)(entry_ime->mb->entry->data);
if (strcmp(mb->code, code) == 0)
{
entry_hz = mb->hz;
return;
}
seek_to_next(entry_ime->mb);
}
entry_hz = NULL;
return;
}
// 释放汉字输入模块
void free_ime()
{
seek_to_first(ime_list);
CODE_TYPE *temp_ime;
while(ime_list->entry != NULL)
{
// 释放每个输入模块
temp_ime = (CODE_TYPE *)(ime_list->entry->data);
seek_to_next(ime_list);
// 释放码表
{
seek_to_first(temp_ime->mb);
while(temp_ime->mb->entry != NULL)
{
// 释放码表
MB *temp_mb = (MB *)(temp_ime->mb->entry->data);
seek_to_next(temp_ime->mb);
//释放汉字码表
{
seek_to_first(temp_mb->hz);
while(temp_mb->hz->entry != NULL)
{
HZ *temp_hz = (HZ *)(temp_mb->hz->entry->data);
seek_to_next(temp_mb->hz);
free(temp_hz->hz);
}
free_list(&temp_mb->hz);
}
}
free_list(&temp_ime->mb);
}
}
free_list(&ime_list);
}
// 复位汉字列表
void reset_hz_list()
{
if (entry_hz == NULL)
return;
seek_to_first(entry_hz);
}
// 获取汉字
BOOL get_hz(char *buf)
{
if (entry_hz == NULL)
return FALSE;
if (entry_hz->entry == NULL)
return FALSE;
strcpy(buf, ((HZ *)(entry_hz->entry->data))->hz);
seek_to_next(entry_hz);
return TRUE;
}
// 看一个键是否在码元表中
int scan_key_table(int k)
{
for (int i = 0; i < 26; i++)
if (scancode_table[i] == k)
goto _ok;
return -1;
_ok:
int t = 'a';
t += i;
for (i = 0; i < (int)strlen(entry_ime->key); i++)
{
if (entry_ime->key[i] == t)
return t;
}
return -1;
}
// 显示汉字输入面板
BOOL input_panel(char *str)
{
int y = SCREEN_HEIGHT - 1;
WORD line_color;
WORD panel_color = 0x0;
if (Is555)
{
line_color = create_color(31, 31, 31);
}
else
{
line_color = create_color(31, 63, 31);
}
line(screen, 0, y, SCREEN_WIDTH - 1, y, line_color);
y -= 18;
line(screen, 0, y, SCREEN_WIDTH - 1, y, line_color);
rect_fill(screen, 0, y + 1, SCREEN_WIDTH - 1, y + 17, panel_color);
y -= 18;
line(screen, 0, y, SCREEN_WIDTH - 1, y, line_color);
rect_fill(screen, 0, y + 1, SCREEN_WIDTH - 1, y + 17, panel_color);
text_printf(screen, 2, SCREEN_HEIGHT - 17, line_color, "%s", entry_ime->name);
update_screen();
int key = 0, dcount = 0;
char code[256], cc = 0;
char hzstr[1024], hz_c = 0, acount = 0;
*hzstr = '\0';
while(TRUE)
{
key = get_key();
if (key == DIK_ESCAPE)
{
// 取消这次汉字的输入
break;
}
else
{
int ck;
if ((ck = scan_key_table(key)) != -1)
{
// 键入码元表中的某个键
if (cc < entry_ime->len)
{
code[cc++] = ck;
code[cc] = '\0';
rect_fill(screen, 70, SCREEN_HEIGHT - 18, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 2, panel_color);
text_printf(screen, 70, SCREEN_HEIGHT - 17, line_color, "%s", code);
rect_fill(screen, 0, SCREEN_HEIGHT - 36, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 21, panel_color);
text_printf(screen, 0, SCREEN_HEIGHT - 36, line_color, "%s", hzstr);
get_hzlist(code);
reset_hz_list();
int x = 200;
dcount = 0;
acount = 0;
for (int i = 0; i < 8; i++)
{
char buf[256];
if (get_hz(buf))
{
text_printf(screen, x, SCREEN_HEIGHT - 17, line_color, "%d.%s", i + 1, buf);
x += strlen(buf) * 16 + 5;
dcount++;
}
else
break;
}
update_screen();
if (dcount == 1 && entry_ime->autosel == TRUE && cc >= entry_ime->len)
{
LIST *hzl = create_list();
hzl->first = entry_hz->first;
hzl->last = entry_hz->last;
hzl->entry = entry_hz->first;
hzl->count = entry_hz->count;
seek_to_first(hzl);
for (int j = 0; j < acount; j++)
seek_to_next(hzl);
strcat(hzstr, ((HZ *)(hzl->entry->data))->hz);
hz_c += strlen(((HZ *)(hzl->entry->data))->hz);
*code = '\0';
cc = 0;
dcount = acount = 0;
entry_hz = NULL;
rect_fill(screen, 70, SCREEN_HEIGHT - 18, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 2, panel_color);
rect_fill(screen, 0, SCREEN_HEIGHT - 36, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 21, panel_color);
text_printf(screen, 0, SCREEN_HEIGHT - 36, line_color, "%s", hzstr);
update_screen();
delete hzl;
}
}
}
else
{
if (key == DIK_BACKSPACE)
{
// 退格键
if (cc > 0)
{
code[--cc] = '\0';
rect_fill(screen, 70, SCREEN_HEIGHT - 18, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 2, panel_color);
text_printf(screen, 70, SCREEN_HEIGHT - 17, line_color, "%s", code);
get_hzlist(code);
reset_hz_list();
int x = 200;
dcount = 0;
acount = 0;
for (int i = 0; i < 8; i++)
{
char buf[256];
if (get_hz(buf))
{
text_printf(screen, x, SCREEN_HEIGHT - 17, line_color, "%d.%s", i + 1, buf);
x += strlen(buf) * 16 + 5;
dcount++;
}
else
break;
}
update_screen();
}
else
{
// 删除已输入的字符串
if (hz_c > 0)
{
if (hz_c > 1)
{
if ((unsigned char)hzstr[hz_c - 2] >= 0xa1)
{
// 要删除的是汉字
hzstr[hz_c - 2] = '\0';
hz_c -= 2;
rect_fill(screen, 0, SCREEN_HEIGHT - 36, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 21, panel_color);
text_printf(screen, 0, SCREEN_HEIGHT - 36, line_color, "%s", hzstr);
update_screen();
}
}
}
}
}
else
{
// 向前翻页
if (key == DIK_ADD || key == DIK_EQUALS)
{
if (entry_hz == NULL)
continue;
if (entry_hz->entry == NULL)
continue;
if (entry_hz->entry->next == NULL)
continue;
rect_fill(screen, 70, SCREEN_HEIGHT - 18, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 2, panel_color);
text_printf(screen, 70, SCREEN_HEIGHT - 17, line_color, "%s", code);
int x = 200;
dcount = 0;
for (int i = 0; i < 8; i++)
{
char buf[256];
if (get_hz(buf))
{
text_printf(screen, x, SCREEN_HEIGHT - 17, line_color, "%d.%s", i + 1, buf);
x += strlen(buf) * 16 + 5;
dcount++;
acount++;
}
else
break;
}
update_screen();
}
else
{
if (key == DIK_MINUS || key == DIK_SUBTRACT)
{
// 向后翻页
if (entry_hz == NULL)
continue;
acount -= 8;
if (entry_hz->entry == NULL)
{
// entry_hz->entry为NULL时的处理
entry_hz->entry = entry_hz->last;
if (dcount < 8)
{
// entry_hz->entry = entry_hz->entry->next;
LIST_POINT *lp = entry_hz->entry;
for (int ii = 0; ii < dcount - 1; ii++)
lp = lp->prev;
if (lp == NULL)
{
entry_hz->entry = entry_hz->last->next;
continue;
}
}
LIST_POINT *lp = entry_hz->entry;
for (int ii = 0; ii < dcount; ii++)
lp = lp->prev;
if (lp == NULL)
{
entry_hz->entry = entry_hz->last->next;
continue;
}
for (ii = 0; ii < dcount; ii++)
entry_hz->entry = entry_hz->entry->prev;
entry_hz->entry = entry_hz->entry->prev->prev->prev->prev->prev->prev->prev;
}
else
{
if (entry_hz->entry->prev->prev->prev->prev->prev->prev->prev->prev->prev == NULL)
continue;
for (int ii = 0; ii < dcount; ii++)
entry_hz->entry = entry_hz->entry->prev;
entry_hz->entry = entry_hz->entry->prev->prev->prev->prev->prev->prev->prev->prev;
}
rect_fill(screen, 70, SCREEN_HEIGHT - 18, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 2, panel_color);
text_printf(screen, 70, SCREEN_HEIGHT - 17, line_color, "%s", code);
int x = 200;
for (int i = 0; i < 8; i++)
{
char buf[256];
if (get_hz(buf))
{
text_printf(screen, x, SCREEN_HEIGHT - 17, line_color, "%d.%s", i + 1, buf);
x += strlen(buf) * 16 + 5;
}
else
break;
}
dcount = 8;
update_screen();
}
else
{
if (key == DIK_SPACE)
{
// 空格键的处理
if (entry_hz == NULL)
continue;
LIST *hzl = create_list();
hzl->first = entry_hz->first;
hzl->last = entry_hz->last;
hzl->entry = entry_hz->first;
hzl->count = entry_hz->count;
seek_to_first(hzl);
for (int j = 0; j < acount; j++)
seek_to_next(hzl);
strcat(hzstr, ((HZ *)(hzl->entry->data))->hz);
hz_c += strlen(((HZ *)(hzl->entry->data))->hz);
*code = '\0';
cc = 0;
dcount = acount = 0;
entry_hz = NULL;
rect_fill(screen, 70, SCREEN_HEIGHT - 18, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 2, panel_color);
rect_fill(screen, 0, SCREEN_HEIGHT - 36, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 21, panel_color);
text_printf(screen, 0, SCREEN_HEIGHT - 36, line_color, "%s", hzstr);
update_screen();
delete hzl;
}
else
{
if (key == DIK_TAB)
{
// TAB键的处理
dcount = acount = 0;
*code = '\0';
cc = 0;
entry_hz = NULL;
seek_to_next(ime_list);
if (ime_list->entry == NULL)
seek_to_first(ime_list);
entry_ime = (CODE_TYPE *)(ime_list->entry->data);
rect_fill(screen, 0, SCREEN_HEIGHT - 18, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 2, panel_color);
text_printf(screen, 2, SCREEN_HEIGHT - 17, line_color, "%s", entry_ime->name);
update_screen();
}
else
{
if (key >= DIK_1 && key <= DIK_8)
{
// 数字键的处理
if (entry_hz == NULL)
continue;
int sel = key - DIK_1;
LIST *hzl = create_list();
hzl->first = entry_hz->first;
hzl->last = entry_hz->last;
hzl->entry = entry_hz->first;
hzl->count = entry_hz->count;
seek_to_first(hzl);
for (int j = 0; j < acount + sel; j++)
seek_to_next(hzl);
hz_c += strlen(((HZ *)(hzl->entry->data))->hz);
strcat(hzstr, ((HZ *)(hzl->entry->data))->hz);
*code = '\0';
cc = 0;
dcount = acount = 0;
entry_hz = NULL;
rect_fill(screen, 70, SCREEN_HEIGHT - 18, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 2, panel_color);
rect_fill(screen, 0, SCREEN_HEIGHT - 36, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 21, panel_color);
text_printf(screen, 0, SCREEN_HEIGHT - 36, line_color, "%s", hzstr);
update_screen();
delete hzl;
}
else
{
if (key == DIK_RETURN)
{
// 回车键的处理
strcpy(str, hzstr);
return TRUE;
}
}
}
}
}
}
}
}
}
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -