SWT 控制 setRedraw 行为

SWT Control setRedraw behavior

使用 SWT Control#setRedraw 在 Windows 上进行实验,我发现 WM_SETREDRAW 并不总是被发送。

发送给stop/start重绘的OS消息由变量drawCount保护。
这似乎意味着如果我执行以下操作:

control.setRedraw(true);  // drawCount: -1
control.setRedraw(true);  // drawCount: -2
control.setRedraw(true);  // drawCount: -3
control.setRedraw(false); // drawCount: -2

然后 WM_SETREDRAW: 0 永远不会发送。
我不明白。这是为什么?

相关代码:

public void setRedraw (boolean redraw) {
    checkWidget ();

    if (drawCount == 0) {
        int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
        if ((bits & OS.WS_VISIBLE) == 0) state |= HIDDEN;
    }
    if (redraw) {
        if (--drawCount == 0) {
            long topHandle = topHandle ();
            OS.SendMessage (topHandle, OS.WM_SETREDRAW, 1, 0);
            if (handle != topHandle) OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0);
            if ((state & HIDDEN) != 0) {
                state &= ~HIDDEN;
                OS.ShowWindow (topHandle, OS.SW_HIDE);
                if (handle != topHandle) OS.ShowWindow (handle, OS.SW_HIDE);
            } else {
                int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_ALLCHILDREN;
                OS.RedrawWindow (topHandle, null, 0, flags);
            }
        }
    } else {
        if (drawCount++ == 0) {
            long topHandle = topHandle ();
            OS.SendMessage (topHandle, OS.WM_SETREDRAW, 0, 0);
            if (handle != topHandle) OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0);
        }
    }
}

setRedraw 的 Javadoc 说

Nested calls to this method are stacked

drawCount 代码正在执行此操作。

这将允许代码调用 setRedraw(false) 然后调用其他代码来重绘 on/off 而嵌套的 setRedraw 调用不会过早地再次打开绘图。