问题:当我捕获我的 Windows 应用程序的调整大小边框,尤其是顶部或左边框,并调整窗口大小时,窗口的内容会在我拖动时“实时”调整大小,但它们以一种可怕的方式调整大小,看起来像一个明显的错误即使是最新手的用户:窗口对面边缘的内容我正在疯狂地前后拖动抖动/闪烁/跳跃。根据情况,该现象可能如下所示:
一旦我停止拖动,丑陋的现象就会停止,但在拖动过程中它使应用程序看起来很业余和不专业。
毫不夸张地说,这个 Windows 问题有 让成千上万的应用开发者疯狂 .
以下是该现象的两张示例图片,请为 a related question 做好准备来自 Roman Starkov :
抖动:
边界:
另一个例子显示了来自 Kenny Liu 的邪恶“双像”现象(注意快速闪光) :
任务管理器现象的另一个示例视频是 here .
问题:任何遇到过这个问题的开发人员很快就会发现,至少有 30 个 Stack Overflow 问题,有些是最近的,有些是 2008 年的,充满了听起来很有希望但很少奏效的答案。现实是这个问题有多种原因 ,并且现有的 Stack Overflow 问题/答案从未使更广泛的上下文变得清晰。这个问题试图回答:
(这是一个规范的问答,用于解释窗口调整大小抖动的所有不同原因,以便用户可以确定是哪个原因导致了他们的问题并解决了它。正如答案所解释的,上面的所有排列( native /托管,窗口/dialog, XP-10) 归结为只有两个根本原因,但确定您拥有的是哪个是棘手的部分。)
此问题的范围:对于这个问题的范围,这种现象发生在:
不在此问题的范围内:
BitBlts
与父窗口一起应用于您的子窗口),但在窗口调整大小您有一个额外的问题需要处理,这超出了这个问题的范围:您需要让所有子窗口自动移动并与父窗口同步。对于此任务,您可能需要 BeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos
你可以了解他们here和 here .WM_ERASEBKGND
您的 wndproc
中的处理程序只返回 1。WM_ERASEBKGND
是来自 WM_PAINT
之前的 Windows 3.1 的神秘 Windows 残余让您的应用程序有机会在您绘制窗口之前“删除背景”……嗯。如果你让WM_ERASEBKGND
留言进入DefWindowProc()
,这将导致您的整个窗口在每次重绘时都被涂上纯色,通常是白色,包括在实时窗口调整大小期间发生的重绘。结果是丑陋的全窗口闪烁,但不是我们在这个问题中谈论的抖动/闪烁/跳跃类型。拦截WM_ERASEBKGND
立即修复此问题。SetWindowPos()
手动调整一次性窗口大小时您可以看到的丑陋工件。 .但它们不太明显,因为它们只在屏幕上轻弹一瞬间,而不是长时间拖动。WM_ENTERSIZEMOVE/WM_EXITSIZEMOVE
切换到更快、质量较低的绘图模式。消息来检测调整大小。WM_SYSCOMMAND
中可怕的嵌套/模态事件循环拖动过程中:here特别this good answer , here , here , here , 和 here .最佳答案
目录
因为这是一个复杂的、多方面的问题,我建议按以下顺序阅读答案:
SetWindowPos()
BitBlt
和背景填充 以及可以帮助其他人收集见解的源 Material 列表:
请随时以创造性的方式提供更多答案,以避免 2a 中描述的问题,尤其是 2b!
关于windows - 调整窗口大小时如何平滑丑陋的抖动/闪烁/跳跃,尤其是拖动左/上边框(Win 7-10;bg、bitblt 和 DWM)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53000291/