用窗口子類化技術(shù)改進(jìn)Windows編輯框控件的技巧
發(fā)表時(shí)間:2024-06-19 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]作者:張俊鋒、崔華鋒 1.問題的提出 盡管Windows系統(tǒng)提供了豐富的通用控件(如按鈕,編輯框,滑動(dòng)條等),但仍不可能滿足我們實(shí)際應(yīng)用中千差萬(wàn)別的需求,筆者在某項(xiàng)目的開發(fā)工作中就遇見了這樣的問題。項(xiàng)目需要一個(gè)供用戶輸入表格數(shù)據(jù)的接口界面,要求只接收用戶輸入的數(shù)據(jù)信息,并可以利用鍵盤上的光標(biāo)...
作者:張俊鋒、崔華鋒
1.問題的提出
盡管Windows系統(tǒng)提供了豐富的通用控件(如按鈕,編輯框,滑動(dòng)條等),但仍不可能滿足我們實(shí)際應(yīng)用中千差萬(wàn)別的需求,筆者在某項(xiàng)目的開發(fā)工作中就遇見了這樣的問題。項(xiàng)目需要一個(gè)供用戶輸入表格數(shù)據(jù)的接口界面,要求只接收用戶輸入的數(shù)據(jù)信息,并可以利用鍵盤上的光標(biāo)鍵移動(dòng)輸入位置以避免用戶在鍵盤和鼠標(biāo)之間的頻繁切換。簡(jiǎn)單地使用Windows的編輯框控件不僅不能對(duì)輸入字符進(jìn)行有效過濾(如果給編輯框控件加上ES_NUMBER風(fēng)格則只能接收0~9之間的數(shù)字而不能接收小數(shù)點(diǎn)正負(fù)號(hào)等需要的字符),而且無(wú)法移動(dòng)控件。如果重起爐灶自己編程來(lái)實(shí)現(xiàn),其工作量是相當(dāng)可觀的。為此,筆者經(jīng)多次嘗試,終于通過采用窗口子類化方法,很好地解決了上述問題。
2.窗口子類化方法
應(yīng)用程序?yàn)榱说怯浺粋(gè)窗口類,首先要填寫好一個(gè)WNDCLASS結(jié)構(gòu),其中的結(jié)構(gòu)參數(shù)lpfnWndProc就是該類窗口函數(shù)的地址,接著調(diào)用RegisterClass()函數(shù)向Windows系統(tǒng)申請(qǐng)登記這個(gè)窗口類。這時(shí)Windows會(huì)為其分配一塊內(nèi)存來(lái)存放該類的全部信息,這個(gè)內(nèi)存塊稱為窗口類內(nèi)存塊。
當(dāng)應(yīng)用程序要?jiǎng)?chuàng)建一個(gè)屬于某一已登記窗口類的窗口時(shí),Windows便為這個(gè)窗口分配一塊內(nèi)存,即窗口內(nèi)存塊,用來(lái)存放與該窗口有關(guān)的專用信息。這些信息一部分來(lái)自傳遞給窗口創(chuàng)建函數(shù)CreateWindow()或CreateWindowEx()的參數(shù)信息,另一部分則來(lái)自所屬窗口類的窗口類內(nèi)存塊,其中參數(shù)lpfnWndProc便被Windows從窗口類內(nèi)存塊復(fù)制到為新創(chuàng)建窗口分配的窗口內(nèi)存塊中。當(dāng)有消息被發(fā)送到這個(gè)窗口時(shí),Windows檢查該窗口內(nèi)存塊中的窗口函數(shù)地址(lpfnWndProc),并調(diào)用該地址上的函數(shù)來(lái)處理這些消息。
所謂窗口子類化,實(shí)際上就是改變窗口內(nèi)存塊中的有關(guān)參數(shù)。由于這種修改只涉及到一個(gè)窗口的窗口內(nèi)存塊,因此它不會(huì)影響到屬于同一窗口類的其它窗口的功能和表現(xiàn)。窗口子類化中最常見的是修改窗口內(nèi)存塊中的窗口函數(shù)地址(lpfnWndProc),使其指向一個(gè)新的窗口函數(shù),從而改變?cè)翱诤瘮?shù)的處理方法,改進(jìn)其功能。其基本步驟如下:
。1)編寫子類化窗口函數(shù)。該函數(shù)必須為標(biāo)準(zhǔn)的窗口函數(shù)格式即:
LRESULT CALLBACK SubClassWndProc ( HWND , UINT , WPARAM , LPARAM ) ;
在這個(gè)函數(shù)中對(duì)感興趣的消息進(jìn)行處理,而把未處理或者需要原窗口函數(shù)進(jìn)一步處理的消息傳送給原窗口函數(shù);
(2)利用待子類化窗口的句柄hWnd,調(diào)用GetWindowLong ( hWnd , GWL_WNDPROC ) 函數(shù)獲得原窗口函數(shù)的地址并保存起來(lái);
。3)調(diào)用SetWIndowLong ( hWnd , GWL_WNDPROC , SubClassWndProc ) 把窗口函數(shù)設(shè)置成子類化窗口函數(shù),完成窗口子類化。