8 关闭命令行窗口(2)(harib23h)
做到这一步,接下来我们就来实现用鼠标关闭命令行窗口的功能。当鼠标点击窗口上的“×”按钮时,向命令行窗口任务发送4这个数据,命令行窗口接收到这个数据后则开始执行exit命令的程序。
话说,鼠标的点击是在task_a中处理的,为什么不直接在task_a中调用close_console,而要绕这么个弯子呢?因为如果直接在task_a中关闭命令行窗口的话,由窗口自身所管理的释放定时器及FAT内存空间的部分就难以实现了,因此我们还是选择向命令行窗口发送通知数据这种方式。
由于这次我们只需要将已经实现的功能通过鼠标来进行操作,所以修改起来比较简单。
本次bootpack.c节选
void HariMain(void)
{
(中略)
for (;;) {
(中略)
if (fifo32_status(&fifo) == 0) {
(中略)
} else {
(中略)
if (256 <= i && i <= 511) { /*键盘数据*/
(中略)
} else if (512 <= i && i <= 767) { /*鼠标数据*/
if (mouse_decode(&mdec, i - 512) != 0) {
(中略)
if ((mdec.btn & 0x01) != 0) {
/*按下左键的情形*/
if (mmx < 0) {
(中略)
for (j = shtctl->top - 1; j > 0; j--) {
(中略)
if (0 <= x && x < sht->bxsize && 0 <= y && y < sht->bysize) {
if (sht->buf[y * sht->bxsize + x] != sht->col_inv) {
(中略)
if (sht->bxsize - 21 <= x && x < sht->bxsize - 5 && 5 <= y && y < 19) {
/*点击“×”按钮*/
if ((sht->flags & 0x10) != 0) { /*是否为应用程序
窗口?*/
task = sht->task;
cons_putstr0(task->cons, "\nBreak(mouse) :\n");
io_cli(); /*禁止在强制结束处理时切换任务*/
task->tss.eax = (int) &(task->tss.esp0);
task->tss.eip = (int) asm_end_app;
io_sti();
/*从此开始*/ } else { /*命令行窗口*/
task = sht->task;
io_cli();
fifo32_put(&task->fifo, 4);
/*到此结束*/ io_sti();
}
}
break;
}
}
}
} else {
(中略)
}
} else {
(中略)
}
}
} else if (768 <= i && i <= 1023) { /*命令行窗口关闭处理*/
(中略)
}
}
}
}
我们在bootpack.c中仅仅增加了5行代码。
接下来是console.c,这里其实仅仅增加了3行代码。
本次console.c节选
void console_task(struct SHEET *sheet, int memtotal)
{
(中略)
for (;;) {
(中略)
if (fifo32_status(&task->fifo) == 0) {
(中略)
} else {
(中略)
if (i == 4) { /*点击命令行窗口的“×”按钮*/ /*从此开始*/
cmd_exit(&cons, fat);
} /*到此结束*/
(中略)
}
}
}
好,完工了,简单就是好啊,如果一直都这么简单的话,笔者也能轻松多了……哦,对了,我们还是先“make run”吧。哇,按“×”按钮可以顺利关闭命令行窗口了,成功了!
![]() | ![]() | |
点击这里…… | 窗口就关闭了 |
顺便说一句,在应用程序运行的时候,点击命令行窗口的“×”按钮是不会关闭命令行窗口的。因为如果应用程序运行中关闭了命令行窗口,万一程序调用了显示字符的API,就不知道会造成什么后果了。
应用程序运行时点击“×”按钮命令行窗口也不会关闭