旅途

如果想飞得高,就该把地平线忘掉

窗口的子类化与超类化

1. 子类化 
在一个已经存在的窗口实例基础上产生新的窗口(本质上时改变原窗口的性质:消息护 
理与其他实例属性)。在SDK编程范畴内,子类化就是改变一个窗口实例的窗口函数(通 
过GetWindowLong()和SetWindowLong()),子类化所要做的就是为某窗口实例编写新的 
窗口函数。其操作是在实例级别上进行的。也就是说:子类化影响的是窗口实例的消息 
拦截及其相应处理。 
实际上,所有MFC窗口都是被子类化的窗口(很多体现,如:所有的窗口都共享一个窗口 
函数,所有的窗口包括控件最后都需调用::CreateWindow ()或::CreateWindow Ex 
()。。。。。。)。 
在MFC中子类化的情况有所不同:所有MFC窗口有相同的窗口函数,由该窗口函数根据窗 
口句柄查找窗口实例,在把消息映射到该窗口类(class)得消息处理函数上。为了利用 
MFC的消息映射机制,不宜改变窗口函数(名),MFC也把子类化封装在函数SubclassWi 
ndow()中。但子类化的本质没有变:在实例级别影响窗口的消息及其处理。例: 
Class  B :public A 

  。。。。。。 

A  a; 
B  b; 
HWND ha = a. GetSafeHwnd  (); 
b.SubclassWindow(ha); 
当然A 和B 不一定是继承关系。 
注意:在被子类化的窗口销毁之前,必须执行窗口的反子类化: 
  b.UnSubclassWindow(); 
2 超类化 
与子类化对应,窗口超类化是在窗口类——WNDCLASS或WNDCLASSEX(非MFC类概念)级别 
进行的改变窗口类特征的。一般遵循以下步骤过程:首先,获得一个已存在的窗口类; 
然后设置窗口类;最后注册该窗口类。 
例: 
WNDCLASSEX  wc; 
wc.cbSize = sizeof(wc);//Windows用来进行版本检查的,与窗口特征无关 
GetClassInfoEx(hinst,”XXXXXX”,&wc);// hinst——定义窗口类XXXXXX 
      //的模块的句柄,如为系统定义的窗口类(如:EDIT、BUTTON) 
      //则hinst=NULL.。 
wc.lpszClassName = “YYYYYYY”;//必须改变窗口类的名字 
wc.hbrBackGround = CreateSolidBrush(RGB(0,0.0));//改变背景刷 
wc.lpfnWndProc = NewWndProc;//改变窗口函数 
。。。。。。 
RegisterClassEx(&wc);// 注册新窗口类 
//使用窗口类 
。。。。。。 
::CreateWindow(_T(“YYYYYYYY”,。。。。。); 
显然使用超类化要涉及到SDK中的 CreateWindow(或CreateWindowEx())这就是说:要 
重载MFC中窗口类(class)的Create(或CreateEx())函数,故超类化只能改变自己创建的 
窗口的特征,而不能用于由Windows创建的窗口(如对话框上的按钮就不能进行超类化) 
。而子类化是实例级别上的,只要能获得窗口的实例,就可对其子类化,这是唯一的子 
类化对于超类化的优势,当然,子类化还比较简单。除此,凡是子类化可实现的,超类 
化都可实现,不过超类化用起来较麻烦。 
最后: 
(1) 子类化是在窗口实例级别上的,超类化是在窗口类(WNDCLASS)级别上的。 
(2) 超类化可以完成比子类化更复杂的功能,在SDK范畴上,可以认为子类化是超类化 
的子集。 
(3) 子类化只能改变窗口创建后的性质,对于窗口创建期间无能为力,而超类化可以 
实现 
(4) 超类化不能用于Windows创建的窗口,子类化可以。 
 

posted on 2007-07-18 00:53 旅途 阅读(492) 评论(0)  编辑 收藏 引用 所属分类: 深入windows


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理