实现Tab窗口切换

更详细的讲解和代码调试演示过程,请参看视频
Linux kernel Hacker, 从零构建自己的内核

我们使用操作系统的时候,一个必不可少的功能就是通过Tab间在不同的窗口中来回切换,这种便捷方式使得你不必要挪动鼠标去点击某个窗口,只要不停的按Tab键,直到你的目标窗口被激活为止,一旦窗口被Tab键激活后,对应的窗口会响应你在键盘的输入,我们本节的目的,是在系统中实现这个功能。

实现Tab窗口切换_第1张图片
这里写图片描述

从上图我们可以看到,含有文本框的小窗口获得了输入焦点,也就是小窗口的头部是蓝色,表明它处于活跃状态,而后面的命令控制台,其头部是灰色,表明它处于非活跃状态。当完成本节代码后,我们在键盘上按下Tab键,得到的情况如下:

实现Tab窗口切换_第2张图片
这里写图片描述

我们看到,原来头部是灰色的控制台变成了蓝色,这意味着它被激活了,而原来是蓝色的Message box ,头部变成了灰色,表示它失去了输入焦点。

实现这个功能不难,大体设想是,我们监听键盘输入,如果当前按下的键盘是Tab键,我们得到当前激活的窗口,把它的头部绘制成灰色,然后找到下一个可以被激活的窗口,然后把它的头部绘制成蓝色。

监听键盘输入在CMain函数,所以我们先从该函数的修改入手:

void CMain(void) {
    ....
    int key_to = 0;

    for(;;) {
    ....
    else if (data == 0x0f) {
               if (key_to == 0) {
                   key_to = 1;
                   make_wtitle8(shtctl, shtMsgBox,"task_a", 0);
                   make_wtitle8(shtctl, sht_cons, "console", 1);
               } else {
                   key_to = 0;
                   make_wtitle8(shtctl, shtMsgBox,  "task_a",1);
                   make_wtitle8(shtctl, sht_cons, "console", 0);
               }              

              sheet_refresh(shtctl, shtMsgBox, 0, 0, shtMsgBox->bxsize, 21);
              s
    ....
    }
    ....
}

当Tab键被按下时,系统获得的扫描码是0x0f, 收到这个数值,表示系统接收到了Tab键按下的事件,此时它判断当前获得输入焦点的是哪个窗口,如果当前激活的是Message Box 那么我们就把它的头部绘制成灰色,把命令控制台的头部绘制成蓝色。

绘制窗口头部的函数是make_wtitle8,它的函数原型如下:

void make_wtitle8(struct SHTCTL *shtctl, struct SHEET *sht,char *title, char act);

最后一个参数act 决定了窗口的头部是绘制成灰色还是蓝色,如果act = 0那么函数把窗口的头部绘制成灰色,如果act = 1, 那么函数就把窗口的头部绘制成蓝色。我们再看看它的实现:

void make_wtitle8(struct SHTCTL *shtctl, struct SHEET * sht,  char *title, char act) {
    static char closebtn[14][16] = {
                "OOOOOOOOOOOOOOO@",
                "OQQQQQQQQQQQQQ$@",
                "OQQQQQQQQQQQQQ$@",
                "OQQQ@@QQQQ@@QQ$@",
                "OQQQQ@@QQ@@QQQ$@",
                "OQQQQQ@@@@QQQQ$@",
                "OQQQQQQ@@QQQQQ$@",
                "OQQQQQ@@@@QQQQ$@",
                "OQQQQ@@QQ@@QQQ$@",
                "OQQQ@@QQQQ@@QQ$@",
                "OQQQQQQQQQQQQQ$@",
                "OQQQQQQQQQQQQQ$@",
                "O$$$$$$$$$$$$$$@",
                "@@@@@@@@@@@@@@@@"
        };

    int x, y;
    char c, tc, tbc;
    if (act != 0) {
        tc = COL8_FFFFFF;
        tbc = COL8_000084;
    } else {
        tc = COL8_C6C6C6;
        tbc = COL8_848484;
    }

    boxfill8(sht->buf, sht->bxsize, tbc, 3, 3, sht->bxsize - 4, 20);
    showString(shtctl, sht, 24, 4, tc , title);
 
     for (y = 0; y < 14; y++) {
         for (x = 0; x < 16; x++) {
             c = closebtn[y][x];
             if (c == '@') {
                 c = COL8_000000;
             } else if (c == '$') {
                 c = COL8_848484;
             } else if (c == 'Q') {
                 c = COL8_C6C6C6;
             }
             else {
                 c = COL8_FFFFFF;
             }
 
             sht->buf[(5+y) * sht->bxsize + (sht->bxsize - 21 + x)] = c;
         }
 
     }

}

这部分代码原来是在窗口绘制函数make_window8里面的,现在我们把头部绘制这部分单独拎出来,形成一个独立函数,同时做一些改动。如果输入参数act的值是1,那么把tbc 设置成COL8_000084,这个颜色就是我们上面看到的窗口被激活时,头部显示的深蓝色,如果act的值是0,那么tbc的值转换为COL8_848484这个颜色就是窗口失去输入焦点后对应的灰色。

将上面代码修改编译后,把内核加载到虚拟机,就可以看到相应效果了。更详细的代码讲解和调试演示,请参看视频。

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:


实现Tab窗口切换_第3张图片
这里写图片描述

你可能感兴趣的:(实现Tab窗口切换)