wxPython处理Windows消息的一种实现方法

wxPython处理Windows消息的一种实现方法

wxWidgets可以很方便的处理Windows消息,只要重载wxWindow类中的MSWWindowProc函数就可以了。而wxPython是没提供这个方法的,需要用pywin32模块调用几个Win32 API才能实现处理Windows消息。虽然麻烦了点,但总比没有解决办法要好。

Sometimes you may need to catch a Windows message that is not already handled by wxWidgets, so there is no wxEvent for it. With a bit of help from the PyWin32 modules it is possible to hook into the WndProc chain for a wxWindow and watch for the message you are interested in.

The magic is in the win32gui.SetWindowLong function. When used with the win32con.GWL_WNDPROC flag it causes a new WndProc to be set for the window, and returns the old one. This lets you write a function in Python that can get first crack at all the Windows messages being sent to the window, and if you are not interested in them then pass them on to the original wxWidgets WndProc.

 

方法一:

import wx   
import win32api   
import win32gui   
import win32con   

class TestFrame(wx.Frame):   
    def __init__(self):   
        wx.Frame.__init__(self, None, title="WndProc Test", size=(200,150))   
        p = wx.Panel(self)   

        # Set the WndProc to our function   
        self.oldWndProc = win32gui.SetWindowLong(self.GetHandle(),   
                                                 win32con.GWL_WNDPROC,   
                                                 self.MyWndProc)   

        # Make a dictionary of message names to be used for printing below   
        self.msgdict = {}   
        for name in dir(win32con):   
            if name.startswith("WM_"):   
                value = getattr(win32con, name)   
                self.msgdict[value] = name   


    def MyWndProc(self, hWnd, msg, wParam, lParam):   
        # Display what we've got.   
        print (self.msgdict.get(msg), msg, wParam, lParam)   

        # Restore the old WndProc. Notice the use of wxin32api   
        # instead of win32gui here. This is to avoid an error due to   
        # not passing a callable object.   
        if msg == win32con.WM_DESTROY:   
            win32api.SetWindowLong(self.GetHandle(),   
                                   win32con.GWL_WNDPROC,   
                                   self.oldWndProc)   

        # Pass all messages (in this case, yours may be different) on   
        # to the original WndProc   
        return win32gui.CallWindowProc(self.oldWndProc,   
                                       hWnd, msg, wParam, lParam)   

app = wx.PySimpleApp()   
f = TestFrame()   
f.Show()   
app.MainLoop() 
import wx
import win32api
import win32gui
import win32con

class TestFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="WndProc Test", size=(200,150))
        p = wx.Panel(self)

        # Set the WndProc to our function
        self.oldWndProc = win32gui.SetWindowLong(self.GetHandle(),
                                                 win32con.GWL_WNDPROC,
                                                 self.MyWndProc)

        # Make a dictionary of message names to be used for printing below
        self.msgdict = {}
        for name in dir(win32con):
            if name.startswith("WM_"):
                value = getattr(win32con, name)
                self.msgdict[value] = name


    def MyWndProc(self, hWnd, msg, wParam, lParam):
        # Display what we've got.
        print (self.msgdict.get(msg), msg, wParam, lParam)

        # Restore the old WndProc. Notice the use of wxin32api
        # instead of win32gui here. This is to avoid an error due to
        # not passing a callable object.
        if msg == win32con.WM_DESTROY:
            win32api.SetWindowLong(self.GetHandle(),
                                   win32con.GWL_WNDPROC,
                                   self.oldWndProc)

        # Pass all messages (in this case, yours may be different) on
        # to the original WndProc
        return win32gui.CallWindowProc(self.oldWndProc,
                                       hWnd, msg, wParam, lParam)

app = wx.PySimpleApp()
f = TestFrame()
f.Show()
app.MainLoop()

 

方法二:

import ctypes   
import wx   

from ctypes import c_long, c_int   

# grab the functions we need - unicode/not doesn't really matter   
# for this demo   
SetWindowLong = ctypes.windll.user32.SetWindowLongW   
CallWindowProc = ctypes.windll.user32.CallWindowProcW   


# a function type for the wndprc so ctypes can wrap it   
WndProcType = ctypes.WINFUNCTYPE(c_int, c_long, c_int, c_int, c_int)   

# constants   
GWL_WNDPROC = -4 

class TestFrame(wx.Frame):   
    def __init__(self, parent):   
        wx.Frame.__init__(self, parent)   
        # need to hold a reference to WINFUNCTYPE wrappers,   
        # so they don't get GCed   
        self.newWndProc = WndProcType(self.MyWndProc)   
        self.oldWndProc = SetWindowLong(   
            self.GetHandle(),   
            GWL_WNDPROC,   
            self.newWndProc   
        )   


    def MyWndProc(self, hWnd, msg, wParam, lParam):   
        print msg,wParam,lParam   
        return CallWindowProc(   
            self.oldWndProc,   
            hWnd,   
            msg,   
            wParam,   
            lParam   
        )   

app =wx.App(False)   
f = TestFrame(None)   
f.Show()   
app.MainLoop()

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值