VincentWei / MiniGUI

A modern and mature cross-platform window system for embedded systems and smart IoT devices.
http://www.minigui.com
GNU General Public License v3.0
695 stars 157 forks source link

关于scrollview控件的问题 #107

Closed htk719809837 closed 1 year ago

htk719809837 commented 2 years ago

你好。最近项目引擎由3.0升级到5.0,列表出现了如下问题:

出现的前提是:列表我们自己加了触摸滑动,通过mousemove实现,如果滑动坐标超过某个值,列表也随着刷新。并且很重要的一点是:列表项同时绘制了文字和图片上去。

1、当scrollview列表某一项往下滑动的时候,又刚好只显示一半左右的地方,列表项的图片会消失不见(3.0当时也有这个问题,不过不是很严重) 2、同第一点的场景,现在列表的文字如果是白色,整个文字区域会被填充成整个白色(3.0并未出现该问题) 3、随意滑动列表,第一项默认选中的列表项会被加上白色的底色。(3.0并未出现该问题)

目前已经排除 使用fb双缓存、界面双缓存、scrollview.c scrolled.c 3.0至5.0的部分改动 ,这三个并不会引起上面的问题。

或许是刷新逻辑还是其他的东西影响了,这个比较着急,希望能尽快修复。

VincentWei commented 2 years ago

要在调用 ScrollWindow 之后立即调用 UpdateInvalidClient 函数,否则会出现控件的无效区域被下一个 ScrollWindow 重置的情形,这就会导致控件的刷新不完整的问题。

请按以上逻辑检查 mousemove 消息的处理代码。

htk719809837 commented 2 years ago

我在mousemove最底部加上了这句话,测试了UpdateInvalidClient 并不生效,当前现象只出现在顶部的列表项被滑动到只显示一半有效高度的情况,但是底部并不会出现

VincentWei commented 2 years ago

哦,忘了提醒了,调用 UpdateInvalidClient 之前,要确保内部数据结构的调整已经完成,这包括那些用来维护视口(viewport)位置的信息以及其他重绘需要依赖的信息。如果这些信息没有更新好之后就调用 UpdateInvalidClient,就会导致滚动后的控件内容和重绘时的数据不一致:控件内容滚动了,但重绘仍然依赖以前的内部数据。

如果还有问题,就对照该控件内部对 SCROLLBAR 事件的代码处理逻辑仔细检查。理论上,拖动滚动条上的滑块和用鼠标拖动整个控件的处理逻辑是一样的,区别在于拖动滚动条一次只会水平或者竖直调整,鼠标拖动则可能产生两个方向上的位置变化。

htk719809837 commented 2 years ago

关键是3.0文字不会产生底色呀,我们这边直接就文字区域全部被填充成白色了

VincentWei commented 2 years ago

底层重绘机制有调整。

htk719809837 commented 2 years ago

那我先试试看,不行的话再联系你们

htk719809837 commented 2 years ago

不行,无论怎么测试列表顶部只要有一列只显示一半的情况下,那他就是有白色的背景,不管文字是什么颜色和背景色。前提是文字的附近通过FillBoxWithBitmap画上了一张图

VincentWei commented 2 years ago

请提供可重现问题的代码,最好跟控件的实现没关系的,比如就在一个普通窗口当中按你们的描述绘制图片和文本,然后可以复现提到的问题的,否则我们很难处理。

VincentWei commented 2 years ago

分析对比了 FillBoxWIthBitmap 的代码,可能是因为背景模式被覆盖导致的。

您先在调用 DrawText 之前,调用 SetBkMode(hdc, BM_TRANPARENT) 重置下背景模式,如果文字显示正常,应该就是这个问题导致的。如果是,我们来做相应的修复。如果仍然不能确定,就需要重现代码。

VincentWei commented 2 years ago

当调用 FillBoxWithBitmap 但并未实际绘制该位图(比如位图在可见区域之外)的情况下,会导致其后的文本透明输出变成不透明的,从而出现该现象。

该缺陷和下面的文件:

https://github.com/VincentWei/MiniGUI/blob/rel-5-0/src/newgdi/bitmap.c#L478

中第 478 行开始的如下两行代码有关:

    else
        pdc->bkmode = BM_OPAQUE;

请删除这两行看看是否可以解决该问题。