С python 3 я хотел бы получить дескриптор к другому окну (не часть моего приложения) таким образом, что я могу также:
a) непосредственно получите то окно как снимок экрана или
b) определите его положение и размер и получите его некоторый другой путь
В случае, если это важно, я использую Windows XP (редактирование: работы в Windows 7 также).
Я нашел это решение, но это не совсем, в чем я нуждаюсь, так как это - полный экран и что еще более важно, PIL насколько я знаю еще не поддерживает 3.x.
Вот как это можно сделать с помощью PIL на win32. Учитывая дескриптор окна ( hwnd
), вам понадобятся только последние 4 строки кода. Предыдущее просто поиск окна с "firefox" в заголовке. Поскольку доступен исходный код PIL, вы должны иметь возможность ковыряться в методе ImageGrab.grab (bbox)
и вычислять код Win32, который вам нужен, чтобы это произошло.
from PIL import ImageGrab
import win32gui
toplist, winlist = [], []
def enum_cb(hwnd, results):
winlist.append((hwnd, win32gui.GetWindowText(hwnd)))
win32gui.EnumWindows(enum_cb, toplist)
firefox = [(hwnd, title) for hwnd, title in winlist if 'firefox' in title.lower()]
# just grab the hwnd for first window matching firefox
firefox = firefox[0]
hwnd = firefox[0]
win32gui.SetForegroundWindow(hwnd)
bbox = win32gui.GetWindowRect(hwnd)
img = ImageGrab.grab(bbox)
img.show()
Арс дал мне все части. Я просто собираю эти части вместе для тех, кому нужно сделать скриншот в python 3.x. Далее мне нужно выяснить, как работать с растровой картой win32, не имея PIL, на который можно опереться.
Получение скриншота (передаем hwnd для окна, а не для полного экрана):
def screenshot(hwnd = None):
import win32gui
import win32ui
import win32con
from time import sleep
if not hwnd:
hwnd=win32gui.GetDesktopWindow()
l,t,r,b=win32gui.GetWindowRect(hwnd)
h=b-t
w=r-l
hDC = win32gui.GetWindowDC(hwnd)
myDC=win32ui.CreateDCFromHandle(hDC)
newDC=myDC.CreateCompatibleDC()
myBitMap = win32ui.CreateBitmap()
myBitMap.CreateCompatibleBitmap(myDC, w, h)
newDC.SelectObject(myBitMap)
win32gui.SetForegroundWindow(hwnd)
sleep(.2) #lame way to allow screen to draw before taking shot
newDC.BitBlt((0,0),(w, h) , myDC, (0,0), win32con.SRCCOPY)
myBitMap.Paint(newDC)
myBitMap.SaveBitmapFile(newDC,'c:\\tmp.bmp')
Получение хэндла окна по заголовку (для передачи в вышеуказанную функцию):
def _get_windows_bytitle(title_text, exact = False):
def _window_callback(hwnd, all_windows):
all_windows.append((hwnd, win32gui.GetWindowText(hwnd)))
windows = []
win32gui.EnumWindows(_window_callback, windows)
if exact:
return [hwnd for hwnd, title in windows if title_text == title]
else:
return [hwnd for hwnd, title in windows if title_text in title]