超类与子类(Superclass & Subclass)

Q: 我看了WINX开发包中的文档中,你提到了超类,它是什么概念?我平常只听过子类(Subclass)。

A: 子类化(Subclass)是指替换窗口过程(WNDPROC)。
    超类(Superclass)是替换窗口过程(WNDPROC),并且替换ClassName。
   Subclass不太象继承,而像是一种外挂(Hook)行为。
   Superclass则更像继承,因为生成了新的窗口类,并且继承了行为。
   winx中Subclass和Superclass用同一个类实现。都是winx::SubclassWindow。
   其他界面库一般不提供Superclass。
   
Q: 你说其他界面库不提供Superclass?MFC里继承应该属于Superclass吧?

A: 不,MFC中用的是Subclass。


Q: 我怎么感觉不出二者的区别?我是说用法上和结果上。

A: 两者在用法上有异,但获得的结果确实无太大差别。
   我们以Button为例。如果是Subclass,那么用户先要有一个Button,然后Subclass它。
   也就是说Subclass发生在CreateWindow之后。
   如果是Superclass,那么用户CreateWindow的时候直接传入新的窗口类名称,根本就没有Button被生成。
   当然,这要求CreateWindow之前调用过该窗口类的RegisterClass。
   MFC用的是Subclass。因为CButton类通过DDX技术和对话框上的Button关联的。
   也就是说,MFC中是先有了Button,然后由DDX技术Subclass它。
   所以,一般你看不到Subclass流程。
   
Q: 什么情况下需要用SuperClass?
   哦,我明白了,是不是有了SuperClass技术,用户可以很方便的创建自己的Control?
A: 对了。不需要从零开始。


Q: 对。感觉多数用户自定义控件还是和系统控件有关系的。

A: 是的。这正是Superclass存在的意义。
   你可以想象一下:在以前,你提供一个控件,你要告诉它,先创建Button,然后调用我的Subclass函数。
   而有了Superclass,现在你只需要告诉它窗口类的名字就可以了。
   因为Superclass隐蔽了你从Button继承这个事实。
   
Q: 对。

A: 之所以winx可以有superclass而其他界面库没有,究其原因,还是与屏蔽“窗口类”这个出发点有关。

Q: 对,对,对。以后自己定义的控件也可以可视化开发。

A: 是的。

Q: 指定一下我们自己的窗口类就可以了。
   WINX这种控件感觉是介于系统控件和ActiveX控件之间的一种控件。

A: 是的。这种控件其实就是Windows系统控件的实现方式。
   只是系统控件不需要你主动注册,Windows已经帮你注册好了。

Q: 系统实现这些系统控件不是通过SuperClass吧?它应该是从最一般化的窗口继承而来。

A: 呵呵,当然不是。它们没有什么可以借用的,只好从最基础的winx::Window继承。

Q: 不管是白手起家,还是有点基础,做法都是SuperClass。
   因为winx::Window的基础是DefWindowProc,也是一个窗口过程。


A: 可以这么理解。

Q: 是不是可以这样理解,SubClass只是更改了WndProc,而SuperClass还更改了其他窗口属性?

A: 是的。你的理解完全正确,这正是Subclass与Superclass最本质的区别。
   Superclass可以改窗口类(WNDCLASSEX)的任何数据。WINX就是这么实现的。

 

 


 

 

子类化:

[cpp]  view plain copy
  1. // 保存窗口默认的消息响应函数指针  
  2. WNDPROC pSubclassOldEditProc;  
  3. // 用于替换子类化窗口的消息响应函数  
  4. LRESULT CALLBACK JcEditProcSubClass(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
  5. {  
  6.     switch(message)  
  7.     {  
  8.     case WM_CHAR:  
  9.         {  
  10.             ::MessageBox(hWnd, "WM_CHAR响应", "子类化", MB_OK);  
  11.             return 0;  
  12.         }  
  13.     default: return ::CallWindowProc(pSubclassOldEditProc, hWnd, message, wParam, lParam);  
  14.     }  
  15. }  
  16. // 对创建好的窗体进行子类化代码  
  17. {  
  18.     // 创建  
  19.     HWND hEdit = CreateWindowEx(NULL, "EDIT", "SubClass"  
  20.         , WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL  
  21.         , 100,120, 128, 16, hWnd, NULL, hInstance, NULL);  
  22.     pSubclassOldEditProc = (WNDPROC)::SetWindowLong(hEdit, GWL_WNDPROC, (DWORD)JcEditProcSubClass);  
  23.     // 显示  
  24.     ShowWindow(hEdit, nCmdShow);  
  25.     UpdateWindow(hWnd);  
  26. }  
 

 

超类化:

[c-sharp]  view plain copy
  1. WNDPROC pSuperOldEditProc;// 保存窗口默认消息处理函数  
  2. // 用于替换的超类化消息响应函数  
  3. LRESULT CALLBACK JcEditProcSuper(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
  4. {  
  5.     switch(message)  
  6.     {  
  7.     case WM_CHAR:  
  8.         {  
  9.             ::MessageBox(hWnd, "WM_CHAR响应", "超类化", MB_OK);  
  10.             return 0;  
  11.         }  
  12.     default: return ::CallWindowProc(pSuperOldEditProc, hWnd, message, wParam, lParam);  
  13.     }  
  14. }  
  15. // 创建超类化控件代码  
  16. {  
  17.     // 取得原控件信息  
  18.     WNDCLASSEX myeditClass;  
  19.     ::GetClassInfoEx(hInstance, "EDIT", &myeditClass);  
  20.     // 保存原控件默认消息处理函数  
  21.     pSuperOldEditProc = myeditClass.lpfnWndProc;  
  22.     // 设置替换的消息处理函数  
  23.     myeditClass.lpfnWndProc = JcEditProcSuper;  
  24.     // 指定新的窗口类名字  
  25.     myeditClass.lpszClassName = "JcilyEdit";  
  26.     // 设置结构体大小  
  27.     myeditClass.cbSize = sizeof(WNDCLASSEX);  
  28.     // 注册新信息  
  29.     RegisterClassEx(&myeditClass);  
  30.     // 创建  
  31.     HWND hEdit = CreateWindowEx(NULL, myeditClass.lpszClassName, "SuperClass"  
  32.         , WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL  
  33.         , 100,100, 128, 16, hWnd, NULL, hInstance, NULL);  
  34.     // 显示  
  35.     ShowWindow(hEdit, nCmdShow);  
  36.     UpdateWindow(hWnd);  
  37. }  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值