窗体的消息处理

我们知道一个应用程序一般都不是仅仅有一个窗体组成的,往往是多窗体组成的,比方一个对话框的窗体上有一个button,这里对话框是一个窗体。button也是一个窗体。

假设一个对话框上有100个button。就是100个窗体。这样句柄会比較多。因而出现了DirectUI的设计方法,全部button和主窗体都是同一个窗体,採用分不同区域来绘画而成。这里就遇到了一个问题。每一个窗体是独立存在的,但在前面的样例里,能够看到每一个窗体都是调用PyWndProc函数来处理。

意味着多个窗体的消息都抛给PyWndProc函数处理,这样处理起来仅仅会越来越多。越来越复杂。站在面向对象设计角度来考虑,能否够有一个更好的方案解决呢?这个是能够的。由于Windows里给每一个窗体保留了一个用户数据字段。仅仅要利用这个字段,就能够关联起每一个窗体与消息类之间的关系。比方窗体1就调用窗体1的类来处理消息,窗体2就调用窗体2的类来处理消息,这样每一个窗体的独立性就得到保障。不用操心窗体1的消息会跑到窗体2去。为此。我声明了一个类Controller。用这个类来处理窗体的消息,当然不同的窗体都能够继承这个类,而实现其他的窗体消息处理。创建类Controller的实例之后,把这个实例对象保存到窗体的GWL_USERDATA字段里。參考《Windows API一日一练》介绍创建窗体的函数,例如以下:

HWND CreateWindowEx(

DWORD dwExStyle,//窗体的扩展风格

LPCTSTR lpClassName,//指向注冊类名的指针

LPCTSTR lpWindowName,//指向窗体名称的指针

DWORD dwStyle,//窗体风格

int x,//窗体的水平位置

int y,//窗体的垂直位置

int nWidth,//窗体的宽度

int nHeight,//窗体的高度

HWND hWndParent,//父窗体的句柄

HMENU hMenu,//菜单的句柄或是子窗体的标识符

HINSTANCE hInstance,//应用程序实例的句柄

LPVOID lpParam//指向窗体的创建数据

);

在这个API函数的最后字段lpParam。就是指向窗体用户自己定义的数据,在这里,我把消息处理类对象的指针放到这里。就能够让每一个窗体有自己的消息处理类了。

定义类Controller例如以下:

class Controller:
    def __init__(self):
        self.hWnd = HWND()
    def SetWnd(self, hWnd):
        self.hWnd = hWnd
    def MyWndProc(self, hWnd, Msg, wParam, lParam):
        if Msg == WM_DESTROY:           
            windll.user32.PostQuitMessage(0)
            return 0
        else:
            return windll.user32.DefWindowProcW(hWnd, Msg, wParam, lParam)

在类Controller里。主要有成员变量self.hWnd。它是用来保存每一个窗体的句柄;成员函数MyWndProc是用来处理每一个窗体的消息,假设窗体没有处理。就会把这些消息传递给Windows系统默认处理,而这个处理默认消息的函数是DefWindowProcW函数。由于一个窗体的消息是有非常多的,并非每一个窗体都须要处理这么多消息,因此仅仅有须要的才处理,这样处理方式是非常方便的。


原文地址:https://www.cnblogs.com/liguangsunls/p/6860496.html