【问题标题】:Odd MFC/GDI behaviour (blank image) that doesn't appear when screen is recorded录制屏幕时未出现的奇怪 MFC/GDI 行为(空白图像)
【发布时间】:2011-12-22 05:59:44
【问题描述】:

我正在尝试修复我的程序中的这个奇怪的错误,但我真的不知道它可能是什么。我的程序的这一部分有一个对话框,显示使用 MFC/GDI 的各种项目的预览。当我滚动浏览不同的项目时,有时预览图像会消失并变为空白。但是,它:

  • 仅在某些机器上发生
  • 显然发生在 Windows 7 和 XP 上
  • 不会每次都发生在同一个项目上
  • 截图时项目仍然存在,但正常查看时为空白。
  • 当我试图用断点跟踪它时,似乎在整个代码的随机位置发生。屏幕从图像变为空白并不总是在同一个位置,这让我相信它不会发生在与我的主线程相同的线程中,即使那确实是当时唯一没有被阻塞的线程。这意味着它发生在 Windows 线程或其他东西中,不是吗?

我假设这是某种竞争条件,但屏幕截图中的预览行为尤其让我感到困惑。为什么截屏时可以,但在屏幕上查看时是空白的?是否有一些“打印屏幕”机制绕过屏幕上显示或更新的内容?

我意识到我没有提供太多信息,人们显然无法提供太多帮助,但如果有人能想到任何事情,将不胜感激:)

谢谢!

【问题讨论】:

  • 有人有什么指点吗?谢谢
  • 我还发现,如果我在 OnPaint() 函数中为窗口放置断点,它总是会中断并且只是空白。这听起来像是比赛条件吗?

标签: c++ mfc gdi screen-capture


【解决方案1】:

另一种理论:GDI 资源泄漏

如果您忘记释放 GDI 对象,就会开始发生奇怪的事情 - 包括未绘制的区域。

  1. 运行 taskmgr.exe 并添加“GDI 对象”列。
  2. 运行您的软件并监控 GDI 对象计数。稳定吗?
  3. 如果您的 GDI 对象计数不稳定,请查看相关的 WM_PAINT 处理程序。

这是一个 GDI 泄漏示例:

void CMyWnd::OnPaint()
{
    CPaintDC dc(this);
    dc.SelectObject(&font);
}

必须始终取消选择选定的 GDI 对象:

void CMyWnd::OnPaint()
{
    CPaintDC dc(this);
    CFont *pOldFont = dc.SelectObject(&font);
    // Use font
    dc.SelectObject(pOldFont);
}

【讨论】:

    【解决方案2】:

    当你录屏时,你是在使用 GDI api 读取桌面吗?在这种情况下,任何硬件加速的表面都可能变成黑色(或可能是白色)。要对此进行测试,您可以禁用显卡的硬件加速。如果您的录音机开始工作,那么您已经找到了罪魁祸首!

    要记录这些非 GDI 表面,您可能需要使用 DirectX/OpenGL 读取表面。我将从这篇文章开始:http://www.codeproject.com/KB/dialog/screencap.aspx

    【讨论】:

    • 我的程序没有录屏。我只是使用 printscreen 或屏幕录像机来尝试记录问题。该问题出现在我的程序中,该程序使用 GDI/mfc 在屏幕上绘制绘图/图像。在大多数机器上都没有任何问题,并且屏幕会按原样显示图像,但我可以偶尔在少数随机机器上重现它。使用 PrintScreen 时不会出现此问题。
    猜你喜欢
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 2015-06-21
    • 2011-12-06
    • 2012-11-13
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多