今天说说被误解的 LockWindowUpdate 。
这是 LockWindowUpdate 系列中的第一篇,我将会讲讲它的作用、用途以及(也许最重要的是)对它的误用。
LockWindowUpdate 的作用非常简单。
当一个窗口被锁定时,所有试图绘制它或其子窗口的尝试都会失败。
窗口管理器不会进行绘制,而是记住应用程序尝试绘制到窗口的哪些部分,当窗口解锁时,这些区域将失效,以便应用程序获得另一条 WM_PAINT 消息,从而使屏幕内容与应用程序认为在屏幕上的内容保持同步。
这种 “跟踪应用程序在条件 X 生效时尝试绘制的内容,并在条件 X 不再成立时使其失效” 的行为,您已经以另一种形式看到:CS_SAVEBITS。
从这个意义上说,LockWindowUpdate 执行的记录工作与用 CS_SAVEBITS 窗口覆盖锁定窗口时发生的工作相同,只是它不保存任何数据位。
MSDN 文档明确指出: 一次只能锁定一个窗口(当然是每个桌面),但函数原型暗示了这一点。
如果可以同时锁定两个窗口,则不可能可靠地使用 LockWindowUpdate。如果这样做会发生什么:
LockWindowUpdate(hwndA); // 锁定窗口 A
LockWindowUpdate(hwndB); // 再锁定窗口 B
LockWindowUpdate(NULL); // 这会发生什么?
对 LockWindowUpdate 的第三次调用有什么作用?
它会解锁所有窗户吗?还是只是窗口 A?还是只是窗口 B?无论您的答案是什么,它都会使以下代码无法可靠地使用 LockWindowUpdate:
>> 请移步至 www.topomel.com 以查看图片 <<
假设 BeginOperation 函数启动了由异步活动触发的某些操作。例如,假设操作 A 正在绘制拖放反馈,因此它在鼠标按下时开始,在释放鼠标时结束。
现在假设操作 B 在拖放仍在进行时完成。
然后 EndOperationB 将清理操作 B 并调用 LockWindowUpdate(NULL)。如果您建议应该解锁所有窗口,那么您刚刚破坏了操作 A,该操作期望 hwndA 仍处于锁定状态。
同样,如果您认为它应该只解锁 hwndA,那么只有操作 A 会被破坏,但操作 B 也会被破坏(因为即使操作完成,hwndB 仍然被锁定)。
另一方面,如果您建议 LockWindowUpdate(NULL) 应解锁 hwndB,则考虑操作 A 首先完成的情况。
如果 LockWindowUpdate 能够一次锁定多个窗口,则必须更改函数原型,以便解锁操作知道正在解锁哪个窗口。
有很多方法可以做到这一点。例如,可以添加新参数或创建单独的函数。
>> 请移步至 www.topomel.com 以查看图片 <<
但事实并非如此。
LockWindowUpdate 函数一次仅锁定一个窗口。当我们了解 LockWindowUpdate 的用途时,其原因将变得更加清晰。
总结
此文献给老是整不明白 LockWindowUpdate 和 RedrawWindow 区别的你(我)。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《What does LockWindowUpdate do?》