⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ime.cpp

📁 vc写的源程序,是关于游戏类的程序。调用了系统的很多API
💻 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 + -