永远不要超过PumpMessages

时间:2013-12-20 20:11:55

标签: winapi python-3.x win32com win32gui

我正在编写一个脚本,该脚本通过程序的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!")

在我的代码中,我可以成功发送和接收消息,但我不确定如何允许我的脚本执行其他操作。我的目标是将其用作基类,然后将其合并到其他脚本中。

我不确定如何:

  1. 通过pumpmessage()函数
  2. 处理课堂外的消息。
  3. 非常感谢任何帮助。

2 个答案:

答案 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()