如果你曾經(jīng)在 Windows 環(huán)境下編過程序,有時(shí)候就會(huì)發(fā)現(xiàn):有一個(gè)現(xiàn)成的窗口,幾乎有你所需要的全部功能,但還不完全一樣。如果你需要一個(gè)具有過濾特殊字符功能的 Edit 控件。當(dāng)然最直接的方法就是自己用代碼來實(shí)現(xiàn),但這的確是一個(gè)費(fèi)時(shí)又很困難的任務(wù),而子類化就可以用來做這種事情。 子類化允許你接管被子類化的窗口,使你對(duì)它有絕對(duì)的控制權(quán)。舉個(gè)例子了來闡明一下:例如你需要一個(gè)只接受十六進(jìn)制數(shù)字輸入的文本編輯框,如果使用一個(gè)簡單的 Edit控件,當(dāng)用戶輸入十六進(jìn)制以外的字符時(shí),你既不知道也無計(jì)可施。也就是說,當(dāng)用戶進(jìn)文本框中輸入字符串 現(xiàn)在來解釋實(shí)現(xiàn)細(xì)節(jié):當(dāng)用戶往文本框中輸入字符時(shí),Windows 會(huì)給Edit控件的窗口函數(shù)發(fā)送WM_CHAR 消息。這個(gè)窗口函數(shù)本身寄生于 Windows 中,因此不能直接修改它。但是我們可以重定向這個(gè)消息使之發(fā)送到我們自己編寫的窗口處理函數(shù)。如果自定義窗口要處理這個(gè)消息那就可以處理它,如果不處理就可以把這個(gè)消息轉(zhuǎn)發(fā)到它原來窗口處理函數(shù)。通過這種方式,自定義的窗口處理函數(shù)就把它自己插入到 Windows 系統(tǒng)和 Edit 控件之間。 說明 看下面的流程: 窗口子類化之前 Windows ==Edit控件的窗口處理函數(shù)。 子類化之后 Windows ==自定義的窗口處理函數(shù)== Edit 控件的窗口處理函數(shù)。 ,那Windows 不就把消息發(fā)到自定義的窗口函數(shù)了嗎! 我們通過調(diào)用函數(shù)SetWindowLong 來實(shí)現(xiàn)這個(gè)任務(wù),此函數(shù)的原型為: SetWindowLong PROTOhWnd:DWORD, nIndex:DWORD, dwNewLong:DWORD hWnd = 將要實(shí)施子類化的窗口的句柄 nIndex = 函數(shù)了功能索引 GWL_EXSTYLE 設(shè)置窗口的擴(kuò)展風(fēng)格. GWL_STYLE 設(shè)置新的窗口風(fēng)格 GWL_WNDPROC 設(shè)置新的窗口處理函數(shù)地址 GWL_HINSTANCE 設(shè)置新的應(yīng)用程序句柄 GWL_ID 設(shè)置新的窗口標(biāo)識(shí) GWL_USERDATA 設(shè)置一個(gè)與這個(gè)窗口相關(guān)的給用戶使用的32位的數(shù)據(jù) dwNewLong = 用來更新的數(shù)據(jù) 我們的工作還是比較簡單的: 寫一個(gè)窗口函數(shù)用于處理發(fā)給 Edit 控件的消息。 用參數(shù)GWL_WNDPROC調(diào)用SetWindowLong 函數(shù),如果調(diào)用成功那么返回值就是與調(diào)用功能相聯(lián)系的一個(gè)32位的整數(shù) 在我們的程序中,返回值就是原先窗口函數(shù)的地址。我們要保存這個(gè)值以便以后使用。 記?。河幸恍┪覀儾惶幚淼南?,需要把它們派遣給原來的窗口函數(shù)來處理,這就用到另外一個(gè)函數(shù) CallWindowProc, 函數(shù)原型為: lpPrevWndFunc = 窗口原來函數(shù)的地址. 剩下的四個(gè)參數(shù)就是發(fā)給自定義函數(shù)的參數(shù),直接把它們傳給函數(shù) CallWindowProc 就行了。
|