1

我有一个带有三个 MDI 窗口的应用程序,它们都显示 OpenGL 内容。在 XP 上,一切正常。但是在 Vista/Win7 上,mdi 子窗口不能正确刷新。

启动后,所有窗口都正确显示其内容。但是当我将焦点从一个 mdi 窗口更改为下一个时,这两个窗口被清除(即,它们只显示白色,没有内容)。我不知道为什么窗口会被清除,发生这种情况时它们不会收到任何 WM_* 消息,当然也不会收到 WM_PAINT 消息。

调整这些窗口的大小时,我正确地收到了 WM_PAINT 消息(在 WM_SIZE 之后)并重绘了内容,但随后窗口也被清除了,这导致调整大小时出现奇怪的闪烁。调整大小停止后,窗口保持清除(白色),直到我手动强制刷新。

这与启用或禁用 Aero 无关。

知道为什么会这样吗?

4

1 回答 1

3

我很惊讶它可以在 XP 上运行。在我涉足 OpenGL 的(有限)经验中,WM_PAINT 并不总是重绘 OpenGL 场景的最佳位置。内容很可能在驱动程序级别被清除。您可以通过查看当您的一个 MDI 窗口碰巧跨越连接到两个不同视频卡的两台显示器时发生的情况来检查这一点。

尝试以下操作:

  1. 在 WM_SIZE 发生后重新初始化您的 OpenGL 上下文。
  2. 按需绘制而不是在 WM_PAINT 中绘制。在 WM_PAINT 的处理程序中,什么都不做。使用计时器或其他机制定期触发显示器更新。
  3. 闪烁通常是由 WM_ERASEBKGND 的干扰引起的。如果您还没有,请拦截 WM_ERASEBKGND 并且在您显示 OpenGL 内容的区域中不执行任何操作。
  4. 在托管 OpenGL 内容的任何窗口上使用 CS_OWNDC 窗口样式,以便 HDC 在 MDI 窗口的生命周期内不会更改每个消息/每个调用。

可能适用的其他更罕见的干扰原因(因为您使用的是 MDI 窗口)

  1. WM_NCPAINT 和其他相关的非客户端绘图消息 - 您可以通过将 OpenGL 内容移动到 MDI 窗口内的无边框子窗口来解决这些问题。
  2. 视频卡上 OpenGL 的不正确/不兼容的默认功能明确需要覆盖或隐式使用它们(重叠上下文中问题的常见原因)。不幸的是,在我的知识范围之外进行诊断,但一些测试可能会在这里提供一些额外的信息。
于 2009-11-17T17:05:03.027 回答