【问题标题】:Win32 application windows eventually stop painting on Windows 7Win32 应用程序窗口最终停止在 Windows 7 上绘制
【发布时间】:2012-09-09 15:59:54
【问题描述】:

我有一个用 C++(没有 MFC 或 .NET)编写的大型复杂应用程序。最积极地使用该软件的客户端将在启动它的一个小时左右内进入所有窗口停止绘制的状态。我们收到有关应用程序“挂起”的报告,因为据他们所知,没有任何事情发生。实际上,应用程序正在运行,只是没有显示任何内容。

我尝试了很多不同的方法都无济于事。我没有想法......

【问题讨论】:

  • 如果您在表单上看不到任何控件,如何知道应用程序正在运行?
  • 我运行任务管理器并结束任务——此时应用程序会弹出确认关闭/询问您是否要保存/等等。好像没有任何问题。

标签: winapi user-interface windows-7 interface paint


【解决方案1】:

你可能已经预感它是什么——你在第一句话中就给出了它

...大型、复杂的应用程序...

听起来您在某处发生了 GDI 资源泄漏。要确认这一点,请尝试在任务管理器中为您的进程查看 GDI 对象。在某些时候,您的应用程序的大多数 GDI 操作都会失败。

确保您正确释放所有句柄。请注意,不同的 GDI 对象需要不同的释放对象的方法。例如GetDCReleaseDC 释放,但CreateDCDeleteDC 释放。

这就是为什么建议将 RAII 智能对象(如智能指针)用于 C++ 中的资源管理(其中释放由智能对象管理以减少泄漏和错误的可能性)。

【讨论】:

  • 我忘记了任务管理器上的GDI栏;谢谢。该应用程序显然在这里和那里泄漏了一些 GDI 对象。有了足够的使用,这可能会比我预期的更快。我会堵住这些漏洞,看看客户怎么说(更新后续)。
  • 忘了回来说:(这是问题所在,塞了几个洞后问题解决了。
  • 这篇文章拯救了我的工作。在向我们的客户端发送源代码前还剩 1 小时,我的 win32 应用程序每 3 小时崩溃一次(主窗体每小时显示和隐藏 1000 次,每次背景更改)。这个答案帮助我找到了 GDI 对象的根本原因。我通过在为画笔变量分配新值之前删除画笔对象来修复。
【解决方案2】:

您的应用程序实际上可能遇到了被忽略的异常。见Microsoft KB article 976038

【讨论】:

  • 默默地忽略回调中未处理的 SEH 异常不会表现出 OP 所描述的行为。毕竟,他们的应用程序仍然功能齐全,除了更新 GUI。在绝大多数情况下,这是由 GDI 资源不足引起的。您需要解释为什么知识库文章中概述的实现会导致观察到的行为。
  • @IInspectable 抱歉,我不记得那么久了,但我猜我的应用程序在其绘制回调中遇到了异常。
【解决方案3】:

我敢打赌,应用程序正在泄漏 GDI 对象,并且当此进程的 GDI 专用空间用尽时,它就无法再绘制自己了。

您可以通过向 Windows 任务管理器(或任何其他进程管理器,例如 进程监视器)添加 GDI 对象列来检查是否是这种情况 看看这个数字是否会随着时间无限增长。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-10
    • 2015-11-05
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多