消除闪烁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++) {
.....
}
.....
}
1
2
3
4
5
6
7
8
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自己的刷新会导致鼠标的刷新 要更改这个问题 需要做新的刷新算法改进