所以我可以使用 PIL 抓取桌面的截图,然后使用 pywin32 获取它的矩形并裁剪出我想要的部分。但是,如果窗口前面有我想要的东西,它会遮挡我想要截屏的应用程序。有什么办法可以让窗口说应用程序当前正在显示什么?它在某处拥有该数据,即使它前面有其他窗口。
7 回答
I posted working code in the answer here: Screenshot of inactive window PrintWindow + win32gui. It uses the PrintWindow
function.
This is the "correct" way to copy the image of a hidden window, but that doesn't mean that it will always work. It depends on the program implementing the proper message, WM_Print
response.
If you try to use PrintWindow
it doesn't work, then your only remaining option would be to bring the window to the front before taking a BitBlit
.
我通过在拍摄之前给我想要关注的应用程序做了同样的事情:
shell=win32com.client.Dispatch("Wscript.Shell")
success = shell.AppActivate(app_name) # Returns true if focus given successfully.
有一种方法可以做到这一点,使用该PrintWindow
功能。它会导致窗口在另一个表面上重新绘制自身。
如果可以,请尝试保存窗口的顺序,然后将您的应用程序移到前面,截屏,然后快速将其移回。可能会产生一些烦人的闪烁,但总比没有好。
也许您可以将应用程序置于屏幕外,然后截取屏幕截图,然后将其放回原处?
此代码适用于我在后台的应用程序,而不是最小化。
点安装 pywin32
import win32gui
import win32ui
def background_screenshot(hwnd, width, height):
wDC = win32gui.GetWindowDC(hwnd)
dcObj=win32ui.CreateDCFromHandle(wDC)
cDC=dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, width, height)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0,0),(width, height) , dcObj, (0,0), win32con.SRCCOPY)
dataBitMap.SaveBitmapFile(cDC, 'screenshot.bmp')
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
hwnd = win32gui.FindWindow(None, windowname)
background_screenshot(hwnd, 1280, 780)
IIRC,不在 Windows pre-vista 中 - 对于 Aero,每个窗口都有自己的缓冲区,但在此之前,您只需使用获取矩形的方法。我不确定 pywin32 是否支持 Aero。