【发布时间】:2013-12-20 20:11:55
【问题描述】:
我正在编写一个通过程序的 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!")
在我的代码中,我可以成功发送和接收消息,但我不确定如何让我的脚本执行其他操作。我的目标是将此作为基类,然后将其合并到其他脚本中。
我不知道该怎么做:
- 通过 pumpmessage() 函数
- 在课堂外处理消息。
任何帮助将不胜感激。
【问题讨论】:
-
PumpMessages 实现了一个标准的 Windows 消息循环。它循环和处理消息。在线程收到 WM_QUIT 消息之前(通常在 gui 应用程序中关闭主窗口时),您不会期望它返回。
-
@arx:那么有没有更好的等待消息的方法?不幸的是,我真的没有在网上找到很多关于 Python 这类东西的信息/示例。
标签: winapi python-3.x win32com win32gui