通过PrintWindow获取屏幕截图时,如果笔记本电脑屏幕关闭,则不会重绘。

6
我的目标是在笔记本电脑屏幕关闭时从应用程序中获取截图,但实际上截图始终与关闭屏幕前的内容相同。一旦屏幕关闭,它就不会重新绘制自己,保持冻结状态。
我正在使用Python中的printwindow方法来获取屏幕截图(使用此处描述的方法:Python Screenshot of inactive window PrintWindow + win32gui)。
只要我的笔记本电脑屏幕开着,这种方法就很好用,但如果我将其关闭,它只会返回屏幕关闭前的最后一个图像。我尝试使用win32gui.RedrawWindow,希望它能强制重绘,但我还没有让它工作,即使我尝试了所有不同的标志。我还尝试过使用pyautogui获取截图,但这也有相同的问题。是否有任何方法可以在笔记本电脑屏幕关闭时重新绘制应用程序?

很遗憾,我没有。 - Nulinspiratie
我认为这与资源泄漏无关,因为它在关闭屏幕后立即发生。您可以使用SendMessage(win32con.HWND_BROADCAST,win32con.WM_SYSCOMMAND,SC_MONITORPOWER,2)轻松重现它,其中SC_MONITORPOWER = 0xF170 - Ruehri
我正在进行以下操作:
  1. 查找具有移动内容的窗口(我使用运行应用程序的安卓模拟器Memu),内置时钟之类的东西可以工作。
  2. 运行连续循环,抓取窗口并将屏幕截图保存到文件中,并带有时间戳(例如,每秒拍摄一次屏幕截图,文件名=时间戳)。
  3. 运行SendMessage命令(屏幕应立即关闭)。
  4. 我所观察到的是,在关闭屏幕之前,屏幕截图始终与窗口同步,当屏幕关闭时,它们停止更新,重新打开屏幕会重新同步。
- Ruehri
注:我在我的台式电脑(Nvidia GPU)和笔记本电脑(同样是Nvidia GPU)上测试过。两台机器的结果都一样。 - Ruehri
仿真器很可能无法使用此方法。您正在使用我们看不到的某些代码。最有可能的是,您正在获取桌面DC的截图,这应该始终在开启或关闭屏幕时可用。 - Barmak Shemirani
显示剩余3条评论
1个回答

6
很遗憾,如果没有进行一些复杂的低级工作是不可能直接实现你想要的功能的。
在底层WinAPI中,本地窗口只有在收到WM_PAINT消息时才会重绘自己,并且只有在可见时才会收到此类消息。如果它们位于另一个窗口后面、被拖到屏幕外、最小化或其可见性设置为False,则不会收到消息。当屏幕关闭时,它们也不可见。由于它们不可见,因此从未被告知重新绘制自己。这就是为什么屏幕捕获图像在屏幕关闭后不会更改的原因。
没有命令可以覆盖此操作 - 它是窗口范例的基本组成部分。
一种解决方案是让应用程序在非窗口(例如对话框框)中绘制自身,并捕获该过程而不是捕获屏幕。您还可以通过重写OnPaint并使用定时器来使应用程序无效并定期调用OnPaint函数(因为不会收到WM_PAINT消息)来修改应用程序。
如果我是您,我会重写OnPaint,使我的应用程序将自己绘制到背景上下文位图而不是普通窗口,然后使用定时器定期无效并重绘,并在需要捕获输出时仅获取背景上下文的位图。
如果您不拥有正在运行的应用程序的代码,则仍然可以通过在虚拟机中运行所有内容来使应用程序重新绘制自己。我曾经在过去的许多操作系统版本中成功地进行了无头计算,但现在情况可能已经有所不同,因此请谨慎行事...
有关VMWare下手动截屏的信息在这里
有关Hyper-V下程序截屏的信息在这里

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接