【问题标题】:How do I hook a ctypes.windll.user32.MessageBoxW by using ctypes.windll.user32.SetWindowsHookExW?如何使用 ctypes.windll.user32.SetWindowsHookExW 挂钩 ctypes.windll.user32.MessageBoxW?
【发布时间】:2019-10-29 17:40:08
【问题描述】:

我想做一个笑话程序,它首先打开一个消息框,关闭后另一个消息框出现在随机位置。它会一直这样重复,直到任何事情都扼杀了它的任务。使用 tkinter 消息框然后那些不能被钩住,我必须制作另一个 tkinter 表单(这真的很丑陋并且与 Windows 消息框不同)。所以我切换到 ctypes,问题就开始了。然后我为钩子创建了一个回调函数,当我将该函数传递给 ctypes.windll.user32.SetWindowsHookExA 函数的第二个参数时,它会显示 TypeError: wrong type。我该如何解决这个问题?

我尝试将函数转换为 c_void_p,但这样做只会得到更多错误,例如“非法指令”。

这是我的代码:

import ctypes, random

def msgBoxHook(nCode, wParam, lParam):
 if nCode == 3:
  hwnd = ctypes.wintypes.HWND
  hwnd = wParam

  msgRekt = ctypes.wintypes.RECT # >:)

  ctypes.windll.user32.GetWindowRect(hwnd, ctypes.byref(msgRekt))
  ctypes.windll.user32.MoveWindow(hwnd, randint(0, ctypes.windll.user32.GetSystemMetrics(0)), randint(0, ctypes.windll.user32.GetSystemMetrics(1)), msgRekt.right - msgRekt.left, msgRekt.bottom - msgRekt.top, True)
 return ctypes.windll.user32.CallNextHookEx(0, nCode, wParam, lParam)

# When I try to call
ctypes.windll.user32.SetWindowsHookExA(5, msgBoxHook, 0, ctypes.windll.kernel32.GetCurrentThreadId())

# It shows:
"""
Traceback (most recent call last):
  File "test.py", line 1, in <module>
ctypes.ArgumentError: argument 2: <class 'TypeError'>: wrong type
"""

预期:当使用 ctypes.windll.user32.MessageBoxW(None, 'Hello', 'World', 0x00000010 | 0x00000000) 时,它会在随机位置打开一个消息框,标题为 'World'、文本 'Hello' 和停止图标带有确定按钮。

现实:如上图。

【问题讨论】:

标签: python ctypes


【解决方案1】:

上市[Python 3.Docs]: ctypes - A foreign function library for Python

您不能将 Python 对象传递给普通的 C 函数(我的意思是可以,但结果不会是预期的)。

[MS.Docs]: SetWindowsHookExA function 的第 1st 参数是 WH_CBT (5) 时,它需要 [MS.Docs]: CBTProc callback function
所以,你必须包装你的函数:

WH_CBT = 5

HOOKProc = ctypes.WINFUNCTYPE(wintypes.LPVOID, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM)
CBTProc = HOOKProc

hook = ctypes.windll.user32.SetWindowsHookExA(WH_CBT, CBTProc(msgBoxHook), 0, ctypes.windll.kernel32.GetCurrentThreadId())

这应该可以帮助您解决当前的问题。但是你肯定会遇到其他人(这当然可以成为其他问题的主题)。
我已经发现的一个问题是,没有为您使用的任何函数定义 argtypesrestype,因此(几乎)肯定会得到你遇到麻烦(崩溃)。一些例子:

【讨论】:

猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 2014-03-03
  • 1970-01-01
相关资源
最近更新 更多