SWT Control#setRedraw未发送WM_SETREDRAW消息的原因问询
问题原因分析
SWT的Control#setRedraw采用引用计数的逻辑控制WM_SETREDRAW消息的发送,核心触发规则是:只有drawCount的值从0发生跳变时,才会实际发送系统重绘控制消息,drawCount的初始默认值为0。
我们逐行对应你的调用序列分析执行过程:
- 初始状态:
drawCount = 0 - 第一次调用
control.setRedraw(true):进入启用重绘分支,先执行--drawCount得到值-1,不满足==0的触发条件,无消息发送 - 第二次调用
control.setRedraw(true):执行--drawCount得到值-2,不满足触发条件,无消息发送 - 第三次调用
control.setRedraw(true):执行--drawCount得到值-3,不满足触发条件,无消息发送 - 调用
control.setRedraw(false):进入禁用重绘分支,首先判断当前drawCount是否等于0,此时drawCount为-3,条件不成立,因此不会发送WM_SETREDRAW: 0消息,仅执行drawCount++将值更新为-2。
这套设计的初衷是支持嵌套的重绘控制场景:比如多层业务代码都需要临时禁用控件重绘避免闪烁,只有所有调用过setRedraw(false)的代码都配对调用了setRedraw(true)后,才会真正恢复控件重绘。你当前的调用顺序完全不符合设计预期,先连续多次调用启用重绘直接把drawCount拉为负数,后续调用禁用重绘时永远碰不到drawCount == 0的触发阈值,因此目标消息始终不会发送。
正确使用姿势
setRedraw(false)与setRedraw(true)必须一一配对,且禁用操作在前,通常搭配try-finally使用避免计数异常:
control.setRedraw(false); try { // 执行批量控件更新操作 } finally { control.setRedraw(true); }
内容的提问来源于stack exchange,提问作者LppEdd
相关产品推荐
相关产品推荐

