Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(C+;+;/Python)不带插入符号指示器的捕获窗口屏幕截图_Python_C++_Winapi_Window - Fatal编程技术网

(C+;+;/Python)不带插入符号指示器的捕获窗口屏幕截图

(C+;+;/Python)不带插入符号指示器的捕获窗口屏幕截图,python,c++,winapi,window,Python,C++,Winapi,Window,我想通过Python捕获现有运行窗口的屏幕截图。 以下是捕获记事本窗口的示例代码: import time import win32gui import win32ui import win32con import pyautogui def getWindowScreenshot(hwnd, output_file): r = win32gui.GetWindowRect(hwnd) width = r[2] - r[0] height = r[3] - r[1]

我想通过Python捕获现有运行窗口的屏幕截图。
以下是捕获记事本窗口的示例代码:

import time
import win32gui
import win32ui
import win32con
import pyautogui


def getWindowScreenshot(hwnd, output_file):
    r = win32gui.GetWindowRect(hwnd)
    width = r[2] - r[0]
    height = r[3] - r[1]
    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)

    # save the bitmap to a file
    dataBitMap.SaveBitmapFile(cDC, output_file)

    dcObj.DeleteDC()
    cDC.DeleteDC()
    win32gui.ReleaseDC(hwnd, wDC)
    win32gui.DeleteObject(dataBitMap.GetHandle())


# Press the green button in the gutter to run the script.
if __name__ == '__main__':

    window_title = "Untitled - Notepad"
    winHandle = win32gui.FindWindow(None, window_title)
    if winHandle == 0:
        raise RuntimeError(f"Window '{window_title}' is not opening!")

    # Bring the window to foreground in case it is overlap by other windows
    win32gui.SetForegroundWindow(winHandle)
    # Do something with Notepad
    time.sleep(3)

    # Capture the window
    getWindowScreenshot(winHandle, "output.bmp")
但是,有时捕获的图像在输入文本框上会有闪烁的插入符号指示灯。
我的问题是,如何在没有插入符号的情况下捕获屏幕截图


我已经尝试了一些解决方案,但不适合: 解决方案1:

# Bring the window to foreground in case it is overlap by other windows
    win32gui.SetForegroundWindow(winHandle)
    # Do something with Notepad
    time.sleep(3)

    # Make the "Desktop window" focus
    win32gui.SetForegroundWindow(win32gui.GetDesktopWindow())

    # Capture the window
    getWindowScreenshot(winHandle, "output.bmp")
# Bring the window to foreground in case it is overlap by other windows
    win32gui.SetForegroundWindow(winHandle)
    # Do something with Notepad
    time.sleep(3)

    # Click outside of window
    r = win32gui.GetWindowRect(winHandle)
    pyautogui.click(r[2]+1, r[3]+1)

    # Capture the window
    getWindowScreenshot(winHandle, "output.bmp")
在捕获屏幕截图之前,请尝试将“桌面”设置为前景窗口。
但是,命令
win32gui.setforegroundindow(win32gui.GetDesktopWindow())
将引发错误:

pywintypes.error: (0, 'SetForegroundWindow', 'No error message is available')
解决方案2:

# Bring the window to foreground in case it is overlap by other windows
    win32gui.SetForegroundWindow(winHandle)
    # Do something with Notepad
    time.sleep(3)

    # Make the "Desktop window" focus
    win32gui.SetForegroundWindow(win32gui.GetDesktopWindow())

    # Capture the window
    getWindowScreenshot(winHandle, "output.bmp")
# Bring the window to foreground in case it is overlap by other windows
    win32gui.SetForegroundWindow(winHandle)
    # Do something with Notepad
    time.sleep(3)

    # Click outside of window
    r = win32gui.GetWindowRect(winHandle)
    pyautogui.click(r[2]+1, r[3]+1)

    # Capture the window
    getWindowScreenshot(winHandle, "output.bmp")
win32gui.SetForegroundWindow(win32gui.GetDesktopWindow())
替换为
win32gui.ShowWindow(winHandle,4)
,其中
4
SW\u SHOWNOACTIVATE
。 代码运行正常,但记事本窗口在执行后不会失去焦点

解决方案3:

# Bring the window to foreground in case it is overlap by other windows
    win32gui.SetForegroundWindow(winHandle)
    # Do something with Notepad
    time.sleep(3)

    # Make the "Desktop window" focus
    win32gui.SetForegroundWindow(win32gui.GetDesktopWindow())

    # Capture the window
    getWindowScreenshot(winHandle, "output.bmp")
# Bring the window to foreground in case it is overlap by other windows
    win32gui.SetForegroundWindow(winHandle)
    # Do something with Notepad
    time.sleep(3)

    # Click outside of window
    r = win32gui.GetWindowRect(winHandle)
    pyautogui.click(r[2]+1, r[3]+1)

    # Capture the window
    getWindowScreenshot(winHandle, "output.bmp")
使用此解决方案,我尝试在记事本窗口外单击(单击桌面)。此代码似乎可以工作,但如果记事本窗口后面有另一个窗口,则无法工作,如下所示:

执行代码时,它将单击Windows资源管理器窗口。因此,代码可以意外地执行单击操作(例如:意外删除系统文件?)

解决方案4 (摘自@SongZhu MSFT)

当我运行代码时,我仍然看到插入符号始终显示。 和
output.bmp
+
output1.bmp
仍然存在一个带插入符号的图像

系统信息:

  • 视窗101909
  • Python 3.7.9

测试后,我可以使用
SendMessageW
发送
WM\u KILLFOCUS
使插入符号消失

这是对我有用的代码:

import time
import win32gui
import win32ui
import win32con
import pyautogui
from ctypes import windll

def getWindowScreenshot(hwnd, output_file):
    r = win32gui.GetWindowRect(hwnd)
    width = r[2] - r[0]
    height = r[3] - r[1]
    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)

    # save the bitmap to a file
    dataBitMap.SaveBitmapFile(cDC, output_file)

    dcObj.DeleteDC()
    cDC.DeleteDC()
    win32gui.ReleaseDC(hwnd, wDC)
    win32gui.DeleteObject(dataBitMap.GetHandle())


if __name__ == '__main__':

    window_title = "Untitled - Notepad"
    winHandle = win32gui.FindWindow(None, window_title)
    if winHandle == 0:
        raise RuntimeError(f"Window '{window_title}' is not opening!")

    # Bring the window to foreground in case it is overlap by other windows
    win32gui.SetForegroundWindow(winHandle)
    # Do something with Notepad
    windll.user32.SendMessageW(winHandle, win32con.WM_KILLFOCUS, None, None)
    # Capture the window
    getWindowScreenshot(winHandle, "output.bmp")
    time.sleep(0.5)
    getWindowScreenshot(winHandle, "output1.bmp")

我认为正确的术语是“聚焦”;也许你可以使用
win32gui.SetFocus(0)
或者类似的东西?@anatolyg,我试过
win32gui.SetFocus(0)
,但还是不起作用。记事本窗口仍处于焦点状态,然后调用。我测试了代码,似乎在单击窗口时会出现插入符号。也许您可以使用
win32gui.EnableWindow(winHandle,False)
并在捕获后调用
win32gui.EnableWindow(winHandle,True)
在睡眠前调用
EnableWindow
,比如:
win32gui.SetForegroundWindow(winHandle)win32gui.EnableWindow(winHandle,False)time.sleep(3)
SendMessageW(WM_KILLFOCUS)
也为我工作。谢谢!