1. 子類化
改變一個(gè)已經(jīng)存在的窗口實(shí)例的性質(zhì):消息處理與其他實(shí)例屬性。
在SDK編程范疇內(nèi),子類化就是改變一個(gè)窗口實(shí)例的窗口函數(shù)(通過GetWindowLong()和SetWindowLong()),子類化所要做的就是為某窗口實(shí)例編寫新的窗口函數(shù)。其操作是在實(shí)例級別上進(jìn)行的。
在MFC中子類化的情況有所不同:所有MFC窗口有相同的窗口函數(shù),由該窗口函數(shù)根據(jù)窗口句柄查找窗口實(shí)例,在把消息映射到該窗口類(class)得消息處理函數(shù)上。為了利用MFC的消息映射機(jī)制,不宜改變窗口函數(shù)(名),MFC也把子類化封裝在函數(shù)SubclassWindow()中。但子類化的本質(zhì)沒有變:在實(shí)例級別影響窗口的消息及其處理。例:
Class B :public A
{
……
}
A a;
B b;
HWND ha=a.GetSafeHwnd();
b.SubclassWindow(ha); #當(dāng)然A 和B 不一定是繼承關(guān)系。
注意:在被子類化的窗口銷毀之前,必須執(zhí)行窗口的反子類化:
b.UnSubclassWindow();
2 超類化
窗口超類化是在窗口類——WNDCLASS或WNDCLASSEX(非MFC類概念)級別進(jìn)行的改變窗口類特征的。
使用過程:首先獲得一個(gè)已存在的窗口類,然后設(shè)置窗口類,最后注冊該窗口類。
例:
WNDCLASSEX wc;
wc.cbSize=sizeof(wc); //Windows用來進(jìn)行版本檢查的,與窗口特征無關(guān)
GetClassInfoEx(hinst,”XXXXXX”,&wc);
// hinst—定義窗口類XXXXXX的模塊的句柄,如為系統(tǒng)定義的窗口類(如:EDIT、BUTTON)則hinst=NULL.。
wc.lpszClassName = “YYYYYYY”;//必須改變窗口類的名字
wc.hbrBackGround = CreateSolidBrush(RGB(0,0.0));//改變背景刷
wc.lpfnWndProc = NewWndProc;//改變窗口函數(shù)
……
RegisterClassEx(&wc);// 注冊新窗口類
//使用窗口類
……
::CreateWindow(_T(“YYYYYYYY”,……);
故超類化只能改變自己創(chuàng)建的窗口的特征,而不能用于由Windows創(chuàng)建的窗口(如對話框上的按鈕就不能進(jìn)行超類化) 。而子類化是實(shí)例級別上的,只要能獲得窗口的實(shí)例,就可對其子類化,這是唯一的子類化對于超類化的優(yōu)勢。另外,凡是子類化可實(shí)現(xiàn)的,超類化都可實(shí)現(xiàn),不過超類化用起來較麻煩。
3. 總結(jié)
(0) 子類化修改窗口過程函數(shù), 超類化修改窗口類(新的窗口類名)
(1) 子類化是在窗口實(shí)例級別上的,超類化是在窗口類(WNDCLASS)級別上的。
(2) 超類化可以完成比子類化更復(fù)雜的功能,在SDK范疇上,可以認(rèn)為子類化是超類化的子集。
(3) 子類化只能改變窗口創(chuàng)建后的性質(zhì),對于窗口創(chuàng)建期間無能為力(無法截獲ON_CREATE 事件),而超類化可以實(shí)現(xiàn);超類化不能用于Windows創(chuàng)建的窗口,子類化可以。
4. 其他
在 眼見為實(shí)(2):介紹Windows的窗口、消息、子類化和超類化 這里有一個(gè)例子..
可以得出結(jié)論
a) 子類化的classname 是不會變化的, 而超類化使用新注冊classname
b) 子類化 & 超類化 描述的是一個(gè)動作 和實(shí)現(xiàn)方法沒什么關(guān)系..... 主要是子類化是SubclassWindow, SubclassDlgItem, 而超類化是RegisterClassEx(&newwindowclass)
c) 感覺具體沒有必要區(qū)分這些, 實(shí)現(xiàn)功能就行了, 呵呵