Python 获取已创建的窗口的hwnd处理程序
我正在尝试创建一个窗口,然后获取所创建窗口的hwnd 目前,我调用Python 获取已创建的窗口的hwnd处理程序,python,winapi,Python,Winapi,我正在尝试创建一个窗口,然后获取所创建窗口的hwnd 目前,我调用subprocess.run(“run.exe”)来创建窗口,然后继续调用wg.getForeGroundIndow()来获取前台窗口的hwnd,它应该是新创建的窗口。然而,这并不能很好地工作,因为程序必须在被检测为前台之前完成打开,同时用户可能会改变焦点 是否有更一致的方法来获取hwnd 编辑: 以下是我在以下评论的帮助下正在做的事情: def create_window(): user32 = ctypes.windl
subprocess.run(“run.exe”)
来创建窗口,然后继续调用wg.getForeGroundIndow()
来获取前台窗口的hwnd,它应该是新创建的窗口。然而,这并不能很好地工作,因为程序必须在被检测为前台之前完成打开,同时用户可能会改变焦点
是否有更一致的方法来获取hwnd
编辑:
以下是我在以下评论的帮助下正在做的事情:
def create_window():
user32 = ctypes.windll.user32
ole32 = ctypes.windll.ole32
EVENT_OBJECT_CREATE = 0x8000
def callback(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime):
if is_real_window(hwnd):
print(get_text(hwnd), "HOOKED")
user32.UnhookWinEvent(hWinEventHook)
return hwnd
WinEventProcType = ctypes.WINFUNCTYPE(
None,
ctypes.wintypes.HANDLE,
ctypes.wintypes.DWORD,
ctypes.wintypes.HWND,
ctypes.wintypes.LONG,
ctypes.wintypes.LONG,
ctypes.wintypes.DWORD,
ctypes.wintypes.DWORD
)
WinEventProc = WinEventProcType(callback)
user32.SetWinEventHook.restype = ctypes.wintypes.HANDLE
hook = user32.SetWinEventHook(
EVENT_OBJECT_CREATE,
EVENT_OBJECT_CREATE,
0,
WinEventProc,
0,
0,
0
)
if hook == 0:
print('SetWinEventHook failed')
sys.exit(1)
msg = ctypes.wintypes.MSG()
x = subprocess.Popen("C:\\cygwin64\\bin\\mintty.exe")
m = user32.GetMessageW(ctypes.byref(msg), 0, 0, 0)
然而,这面临两个问题。首先,虽然我可以在回调函数中访问hwnd,但似乎没有办法让create_窗口返回这个值。其次,GetMessage窗口继续运行,即使在调用UnhookWinEvent之后也是如此
我能做些什么来修复这些
hwnd
是一个范围问题。
回调函数是异步调用的,因此不可能返回值;
相反,您可以将该值分配给另一个作用域中的变量,例如,分配给
全局变量:
def callback((hWinEventHook, event, hwnd, ...):
global HWND
HWND = hwnd
....
GetMessage
似乎永远都在运行,但实际上它正在等待消息被删除
已发布到其消息队列。
正如合同中所述:
从调用线程的消息队列检索消息。该函数将发送传入的消息,直到已发布的消息可供检索为止
在调用GetMessage之前,请记住存储线程id,例如在全局变量中:
def create_window(..):
global THREAD_ID
THREAD_ID = win32api.GetCurrentThreadId()
...
m = user32.GetMessageW(ctypes.byref(msg), 0, 0, 0)
因此,任何发布到安装了钩子的线程的消息都会使
GetMessage停止“运行”并返回一个值:
def callback(...):
...
win32gui.PostThreadMessage(THREAD_ID, win32con.WM_QUIT, 0, 0)
# also valid:
# win32gui.PostThreadMessage(THREAD_ID, win32con.WM_MOVE, 0, 0)
UnhookWinEvent
的位置在GetMessage
之后,因此当后面的
退出时,将执行下一步的取消挂钩操作:
def create_window(hWinEventHook, event, hwnd, ...):
...
m = user32.GetMessage(ctypes.byref(msg), 0, 0, 0)
user32.UnhookWinEvent( hWinEventHook )
return HWND
hwnd
与其可执行文件匹配,
有一个有用的getProcessFileaname
函数,它返回完整路径
到可执行文件(感谢本文作者
)
hwnd
是一个范围问题。
回调函数是异步调用的,因此不可能返回值;
相反,您可以将该值分配给另一个作用域中的变量,例如,分配给
全局变量:
def callback((hWinEventHook, event, hwnd, ...):
global HWND
HWND = hwnd
....
GetMessage
似乎永远都在运行,但实际上它正在等待消息被删除
已发布到其消息队列。
正如合同中所述:
从调用线程的消息队列检索消息。该函数将发送传入的消息,直到已发布的消息可供检索为止
在调用GetMessage之前,请记住存储线程id,例如在全局变量中:
def create_window(..):
global THREAD_ID
THREAD_ID = win32api.GetCurrentThreadId()
...
m = user32.GetMessageW(ctypes.byref(msg), 0, 0, 0)
因此,任何发布到安装了钩子的线程的消息都会使
GetMessage停止“运行”并返回一个值:
def callback(...):
...
win32gui.PostThreadMessage(THREAD_ID, win32con.WM_QUIT, 0, 0)
# also valid:
# win32gui.PostThreadMessage(THREAD_ID, win32con.WM_MOVE, 0, 0)
UnhookWinEvent
的位置在GetMessage
之后,因此当后面的
退出时,将执行下一步的取消挂钩操作:
def create_window(hWinEventHook, event, hwnd, ...):
...
m = user32.GetMessage(ctypes.byref(msg), 0, 0, 0)
user32.UnhookWinEvent( hWinEventHook )
return HWND
hwnd
与其可执行文件匹配,
有一个有用的getProcessFileaname
函数,它返回完整路径
到可执行文件(感谢本文作者
)
你控制这两个过程的代码吗?不知道你的意思。我控制调用的python代码,但不控制正在执行的程序。你想用这个应用程序的窗口做什么?我需要hwnd来实现各种各样的功能。设置窗口样式、移动窗口等,因此仅在创建窗口时对其执行某些操作是不够的;我需要HwndWaitForInput和EnumWindows。您是否控制这两个进程的代码?不确定这是什么意思。我控制调用的python代码,但不控制正在执行的程序。你想用这个应用程序的窗口做什么?我需要hwnd来实现各种各样的功能。设置窗口样式、移动窗口等,因此仅在创建窗口时对其执行某些操作是不够的;我需要HwndWaitForInput和EnumWindows