清除OpenGL窗口时没有WM_PAINT消息

时间:2009-11-17 16:20:42

标签: opengl windows-vista aero

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

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

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

这与Aero启用或禁用无关。

知道为什么会这样吗?

1 个答案:

答案 0 :(得分:2)

我很惊讶它适用于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窗口样式,以便在MDI窗口的生命周期内,HDC不会更改每条消息/每次调用。
  5. 可能适用的其他罕见干扰原因(因为您使用的是MDI窗口)

    1. WM_NCPAINT和其他相关的非客户端绘图消息 - 您可以通过在MDI窗口内将OpenGL内容移动到没有边框的子窗口来解决这些问题。
    2. 视频卡上OpenGL的默认/不兼容默认功能明确需要叠加或隐式使用它们(重叠上下文中常见问题的常见原因)。不幸的是,从我的知识领域中诊断出这一点,但是一些测试可能会在这里提供一些额外的亮点。