1. 程式人生 > >窗體的消息處理

窗體的消息處理

dll str itme 寬度 classname 對象 elf des 父窗體

我們知道一個應用程序一般都不是僅僅有一個窗體組成的,往往是多窗體組成的,比方一個對話框的窗體上有一個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函數。由於一個窗體的消息是有非常多的,並非每一個窗體都須要處理這麽多消息,因此僅僅有須要的才處理,這樣處理方式是非常方便的。


窗體的消息處理