我正在编写一个脚本,该脚本通过程序的WM_COPYDATA api进行交互,但仍然停留在PumpMessage功能上。
import win32con, win32api, win32gui
import ctypes, ctypes.wintypes
FindWindow = ctypes.windll.user32.FindWindowW
SendMessage = ctypes.windll.user32.SendMessageW
class COPYDATASTRUCT(ctypes.Structure):
_fields_ = [
('dwData', ctypes.wintypes.LPARAM),
('cbData', ctypes.wintypes.DWORD),
('lpData', ctypes.c_char_p)
#formally lpData is c_void_p, but we do it this way for convenience
]
PCOPYDATASTRUCT = ctypes.POINTER(COPYDATASTRUCT)
class Stickies:
def __init__(self):
message_map = {
win32con.WM_COPYDATA: self.OnCopyData
}
wc = win32gui.WNDCLASS()
wc.lpfnWndProc = message_map
wc.lpszClassName = 'MyWindowClass'
hinst = wc.hInstance = win32api.GetModuleHandle(None)
classAtom = win32gui.RegisterClass(wc)
self.hwnd = win32gui.CreateWindow (
classAtom,
"win32gui test",
0,
0,
0,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
0,
0,
hinst,
None
)
self.send_message("api do register")
def __enter__(self):
return self
def __exit__(self):
self.send_message("api do deregister")
def send_message(self, msg):
hwnd = FindWindow(None, "ZhornSoftwareStickiesMain")
cds = COPYDATASTRUCT()
cds.dwData = 0
str = msg.encode("ascii")
cds.cbData = ctypes.sizeof(ctypes.create_string_buffer(str))
cds.lpData = ctypes.c_char_p(str)
SendMessage(hwnd, win32con.WM_COPYDATA, self.hwnd, ctypes.byref(cds))
def OnCopyData(self, hwnd, msg, wparam, lparam):
pCDS = ctypes.cast(lparam, PCOPYDATASTRUCT)
msg = pCDS.contents.lpData.decode("ascii", "ignore")
if msg != None:
print(msg)
return 1
s = Stickies()
win32gui.PumpMessages()
# Never gets past previous line
print("Hello, world!")
在我的代码中,我可以成功发送和接收消息,但我不确定如何允许我的脚本执行其他操作。我的目标是将其用作基类,然后将其合并到其他脚本中。
我不确定如何:
非常感谢任何帮助。
答案 0 :(得分:0)
SendMessage
是同步的。将WM_COPYDATA
发送到其他应用程序,您的代码将在Windows内部消息循环中等待,直到您收到回复。
这意味着您的代码可以在等待时响应来自其他应用程序的消息。如果协议涉及消息交换,则可能需要这样做。
如果您要回复未经请求的邮件,则只需要一个邮件循环。
我不确切知道你在做什么,但很可能你可以完全取消对win32gui.PumpMessages
的调用。
答案 1 :(得分:0)
PumpMessages冻结当前线程。如果要在PumpMessages之后执行某些操作,请考虑创建一个新线程并使用线程模块运行该线程:
import threading
import win32gui
def otherCodeToRun(x, y, z):
print("Hello World!")
t = threading.Thread(target=otherCodeToRun, args=(x, y, z, )) // You can leave out args if you don't have any parameters.
t.start()
win32gui.PumpMessages()