Python win32api 发送消息
我想弄清楚win32api的用法。于是我做了一个简单的例子:获取记事本窗口,移动鼠标到一个位置,点击并输入一串字符。但是这个例子没有成功。请问问题出在哪里?
还有,能不能帮我解释一下lParam这个参数是什么?
它有什么作用,是什么类型的,应该是什么样子的?
import win32api, win32con, win32gui, win32ui, win32service, os, time
def f_click(pycwnd):
x=300
y=300
lParam = y <<15 | x
pycwnd.SendMessage(win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, lParam);
pycwnd.SendMessage(win32con.WM_LBUTTONUP, 0, lParam);
def get_whndl():
whndl = win32gui.FindWindowEx(0, 0, None, 'NB.txt - Notepad')
return whndl
def make_pycwnd(hwnd):
PyCWnd = win32ui.CreateWindowFromHandle(hwnd)
return PyCWnd
def send_input_hax(pycwnd, msg):
f_click(pycwnd)
for c in msg:
if c == "\n":
pycwnd.SendMessage(win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
pycwnd.SendMessage(win32con.WM_KEYUP, win32con.VK_RETURN, 0)
else:
pycwnd.SendMessage(win32con.WM_CHAR, ord(c), 0)
pycwnd.UpdateWindow()
whndl = get_whndl()
pycwnd = make_pycwnd(whndl)
msg = "It works !\n"
send_input_hax(pycwnd,msg)
1 个回答
14
在记事本的主窗口里面还有一个隐藏的窗口,你需要把消息发送到这个窗口。你可以使用 Microsoft Spy++ 工具来查看这个“隐藏”的窗口,或者你可以用下面的方法获取所有的子窗口:
def callback(hwnd, hwnds):
if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd):
hwnds[win32gui.GetClassName(hwnd)] = hwnd
return True
hwnds = {}
win32gui.EnumChildWindows(whndl, callback, hwnds)
我们要找的窗口的类名是 'Edit',而且它是记事本唯一一个可用且可见的子窗口。所以你的代码可以这样写:
import win32api, win32con, win32gui, win32ui, win32service, os, time
def f_click(pycwnd):
x=300
y=300
lParam = y << 16 | x
pycwnd.SendMessage(win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, lParam);
pycwnd.SendMessage(win32con.WM_LBUTTONUP, 0, lParam);
def get_whndl():
whndl = win32gui.FindWindowEx(0, 0, None, 'NB.txt - Notepad')
return whndl
def make_pycwnd(hwnd):
PyCWnd = win32ui.CreateWindowFromHandle(hwnd)
return PyCWnd
def send_input_hax(pycwnd, msg):
f_click(pycwnd)
for c in msg:
if c == "\n":
pycwnd.SendMessage(win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
pycwnd.SendMessage(win32con.WM_KEYUP, win32con.VK_RETURN, 0)
else:
pycwnd.SendMessage(win32con.WM_CHAR, ord(c), 0)
pycwnd.UpdateWindow()
whndl = get_whndl()
def callback(hwnd, hwnds):
if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd):
hwnds[win32gui.GetClassName(hwnd)] = hwnd
return True
hwnds = {}
win32gui.EnumChildWindows(whndl, callback, hwnds)
whndl = hwnds['Edit']
pycwnd = make_pycwnd(whndl)
msg = "It works !\n"
send_input_hax(pycwnd,msg)
lParam 是一个整数,这里展示的技巧可以让你通过一个参数传递多个值。比如说,我们需要传递两个数字给一个只接受一个参数的函数。我们可以把它们作为一个两位数传过去,然后在函数内部再拆分开。类似的,位移运算(<<)和按位或运算(|)在你的情况下也是可以反向操作的:
>>> x = 300
>>> y = 300
>>> lParam = y << 16 | x
>>> lParam & 0x7FFF # x
0: 300
>>> lParam >> 16 # y
1: 300
你可以在 维基百科 和 Python Wiki 上了解更多关于位运算的内容。