GUI下编辑文本文件

本章的最后,我们还是要将上一节实现的编辑功能集成到GUI模式中。本节示例代码的目录为gui-edit (日文版为sample5_6_gui_edit)。

这里我们要实现下面这两点功能:

  1. 在文件图标或是空白处右键进入编辑器
  2. 按Esc键退出编辑模式

回忆一下,要新建一个文件,我们需要把Open函数中的OpenMode参数或上模式位EFI_FILE_MODE_CREATE

这里要修改的文件是gui.cshell.c。代码6.21展示了修改后的gui.c

/* ...省略... */ void gui(void) { unsigned long long status; struct EFI_SIMPLE_POINTER_STATE s; int px = 0, py = 0; unsigned long long waitidx; int file_num; int idx; unsigned char prev_lb = FALSE; unsigned char prev_rb = FALSE, executed_rb; /* 新增 */ SPP->Reset(SPP, FALSE); file_num = ls_gui(); while (TRUE) { ST->BootServices->WaitForEvent(1, &(SPP->WaitForInput), &waitidx); status = SPP->GetState(SPP, &s); if (!status) { /* ...省略... */ /* 清除“已处理过右键事件”标志 */ executed_rb = FALSE; /* 新增 */ /* 处理文件图标 */ for (idx = 0; idx < file_num; idx++) { if (is_in_rect(px, py, file_list[idx].rect)) { /* ...省略... */ if (prev_lb && !s.LeftButton) { cat_gui(file_list[idx].name); file_num = ls_gui(); } /* 新增(此处开始) */ if (prev_rb && !s.RightButton) { edit(file_list[idx].name); file_num = ls_gui(); executed_rb = TRUE; } /* 新增(此处结束) */ } else { /* ...省略... */ } } /* 新增(此处开始) */ /* 新建文件 */ if ((prev_rb && !s.RightButton) && !executed_rb) { /* 处理文件图标外的右键单击事件 */ dialogue_get_filename(file_num); edit(file_list[file_num].name); ST->ConOut->ClearScreen(ST->ConOut); file_num = ls_gui(); } /* 新增(此处结束) */ /* 保存鼠标按键状态 */ prev_lb = s.LeftButton; prev_rb = s.RightButton; /* 新增 */ } } }

代码6.21: gui-edit/gui.c

代码6.21增加了对于单击右键进入编辑模式的处理。对于已经存在的文件,这个过程仍然在处理文件图标的循环中进行;对于新建文件,则在这个循环之后。变量executed_rb用来标记右键事件是否已经在处理文件图标这一循环中被处理。

另外,我们在shell.c中加入了新建文件时询问文件名的函数dialogue_get_filename,并且在edit函数调用Open函数时或上了模式位EFI_FILE_MODE_CREATE。代码6.22展示了修改后的修改后的shell.c

/* ...省略... */ /* 新增(此处开始) */ void dialogue_get_filename(int idx) { int i; ST->ConOut->ClearScreen(ST->ConOut); puts(L"New File Name: "); for (i = 0; i < MAX_FILE_NAME_LEN; i++) { file_list[idx].name[i] = getc(); if (file_list[idx].name[i] != L'\r') putc(file_list[idx].name[i]); else break; } file_list[idx].name[(i < MAX_FILE_NAME_LEN) ? i : MAX_FILE_NAME_LEN - 1] = L'\0'; } /* 新增(此处结束) */ /* ...省略... */ void edit(unsigned short *file_name) { /* ...省略... */ status = root->Open(root, &file, file_name, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | \ EFI_FILE_MODE_CREATE, 0); /* 更改 */ assert(status, L"root->Open"); /* ...省略... */ } /* ...省略... */

代码6.22: gui-edit/shell.c

这个例子的运行结果如图6.8、6.9所示。这里展示的是新建文件的操作。

输入文件名的界面

图6.8: 输入文件名的界面

编辑界面

图6.9: 编辑界面