我在我的项目中大量使用BitBlt。我创建了许多线程,并在每个线程中通过BitBlt捕获屏幕。它工作得很好,就像现在预期的那样,除了以下问题。
当用户点击正在运行的程序或者已经打开任务栏上的资源管理器时,问题就会发生。你知道当你点击任务栏上正在运行的程序时,它要么最小化,要么出现在屏幕上。我正在谈论的问题正是在这个过渡中发生的。在那一刻,就像中断一样,所有线程都会在不到一秒的时间内停止捕获屏幕,然后继续捕获。当您在音量控制窗口上向下或向上移动时,也会发生同样的情况。你能解释一下为什么会发生这种情况,以及我如何防止这种情况发生吗?
谢谢。
杰伦
发布于 2013-02-01 01:30:45
这可能是一个日程安排问题。当你激活一个应用程序时,它的优先级会得到一个小的、短暂的提升(以便它在UI中看起来像是响应式的)。这种提升可能会持续动画一样长的时间,并暂时抢占您的屏幕捕获线程。
也有可能是桌面管理器正在序列化东西,而您的bitblt只是暂停,直到动画结束。即使你已经关闭了Aero,我相信desktop window manager可能仍然处于合成模式,这就像Hans Passant在评论中描述的那样。
如果你想从屏幕上制作视频,我认为依靠GDI是不可能的。我强烈建议阅读有关桌面窗口管理器的内容。例如,此caveat直接应用于您正在尝试执行的操作:
避免从显示DC读取或写入显示DC。虽然受DWM支持,但我们不建议这样做,因为性能会降低。
当您使用GDI尝试读取屏幕时,DWM必须停止它正在做的事情,可能会将桌面的新副本呈现到视频内存,并将数据从视频内存复制回系统内存。DWM可能会将这些请求视为比正在进行的动画的优先级更低的请求,所以当它响应BitBlt时,动画就结束了。
这个question建议使用带有屏幕捕获过滤器的DirectShow。
https://stackoverflow.com/questions/14627878
复制相似问题