MacOS环境-手写操作系统-23-消除刷新的闪烁 原创

消除闪烁1

1.简介

就以前几节我们创造的Message box为例

我们修改一下代码 不断的修改Box窗体内的字符 进而导致图层不断刷新

(在上节我们已经出现了这样的问题 22-突破连续读取72个扇区)

运行后 就疯狂的闪烁

这个现象的产生 是因为我们在刷新Box窗体时 我们也同时在刷新底层桌面

假设一个窗体 它的高度是10 那么它刷新时 高度为0到9的窗体根本不需要跟着刷新

如果高度低的窗体跟着刷新 不但产生闪烁的效果

而且是毫无必要的浪费CPU资源

接下来我们的改进就是 当窗体刷新时 只刷新同一层高度或高度更高的图层

2.代码

由此 代码改动如下 在win_sheet.c中

void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0) {
    ....
    for (h = h0; h <= ctl->top; h++) {
       .....
    } 

    .....
}

sheet_refreshsub 是用来刷新图层的

这次改动就增加了一个参数h0

这个h0就表示当前要刷新的图层的高度 在for 循环不再从0开始

而是从h0开始 也就是从当前图层的高度往上进行刷新

其他调用它的函数也要做相应的修改 仍然在win_sheet.c中

int sheet_refresh(struct SHTCTL *ctl, struct SHEET *sht, int bx0, int by0, int bx1, int by1) {
    if (sht->height >= 0) {
        //多添加一个图层高度的参数
        sheet_refreshsub(ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1,
        sht->vy0 + by1, sht->height);
    }
    return 0;
}

void sheet_slide(struct SHTCTL *ctl, struct SHEET *sht, int vx0, int vy0) {
    int old_vx0 = sht->vx0, old_vy0 = sht->vy0;
    sht->vx0 = vx0;
    sht->vy0 = vy0;
    if (sht->height >= 0) {
         sheet_refreshsub(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0);
         sheet_refreshsub(ctl, vx0, vy0, vx0+sht->bxsize, vy0+sht->bysize, sht->height);
    }
}

void sheet_slide(struct SHTCTL *ctl, struct SHEET *sht, int vx0, int vy0) {
    int old_vx0 = sht->vx0, old_vy0 = sht->vy0;
    sht->vx0 = vx0;
    sht->vy0 = vy0;
    if (sht->height >= 0) {
         //多添加一个图层高度的参数
         sheet_refreshsub(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0);
         sheet_refreshsub(ctl, vx0, vy0, vx0+sht->bxsize, vy0+sht->bysize, sht->height);
    }
}

void sheet_updown(struct SHTCTL *ctl, struct SHEET *sht, int height) {
     ....
       if (old > height) {
         ....
           if (height >= 0) {
         .....

         //多添加一个图层高度的参数
           sheet_refreshsub(ctl, sht->vx0, sht->vy0, 
           sht->vx0+sht->bxsize, sht->vy0+sht->bysize, height+1);
            }
       } else {
           ....
           //多添加一个图层高度的参数
            sheet_refreshsub(ctl, sht->vx0, sht->vy0, 
            sht->vx0+sht->bxsize, sht->vy0+sht->bysize,0);
       }
    else {
        ....
        //多添加一个图层高度的参数
        sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0+sht->bxsize, sht->vy0+sht->bysize,
        height);
   }
}

唯一需要改动的就是在调用sheet_refreshsub时 多添加一个参数 把当前更新图层所在的高度传进去

3.编译运行

图层的闪烁现象就消除了

但如果我们把鼠标挪到 Message Box 的上头

我们会发现鼠标自己出现了闪烁的现象

这是因为鼠标图层比Message Box 高

当鼠标与Box重叠时 Box自己的刷新会导致鼠标的刷新 要更改这个问题 需要做新的刷新算法改进

在这里插入图片描述

posted @   武子康  阅读(0)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示