`
lovnet
  • 浏览: 6881168 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

MFC的子类化技术

阅读更多

Windows是一个基于消息的系统,消息在Windows的对象之间进行着传递。子类化和Windows的钩子机制存在于消息系统之中,我们可以利用这些机制来操纵、修改甚至丢弃那些在操作系统或是进程中传递的消息,以求改变系统的一些行为。子类化技术用来截取窗口或控件之间的消息,当然是消息在到达目的窗口之前完成的操作。这些被截获的消息既可以保留也可以修改它们的状态,之后就继续发送到目的地。子类化技术实现了一些正常情况下无法实现的功能,试想鼠标右键单击TextBox,系统默认弹出Undo、Cut、Copy、Paste等菜单,我们就可以利用子类化技术来改变这个系统菜单。

简单的说,子类化就是创建一个新的窗口消息处理过程,并将其插入到原先的默认窗口消息处理过程之前。子类化分为三类:实例子类化(instance subclassing)—从窗口或控件的单一实例截获消息,这种子类化技术最普遍;全局子类化(global subclassing)—能够截获从相同的窗口类创建出来的多个窗口或控件的消息;超类化(superclassing)—和全局子类化很类似,区别在于可以应用在新的窗口类上面。
  
首先,我们看看这个C++程序:
#include <iostream><br>using namespace std;<br>class Parent<br>{<br>public:<br> void func { cout &lt;&lt; "Parent" &lt;&lt; endl; }<br>};<br>class Child : public Parent<br>{<br>public:<br> void func { cout &lt;&lt; "Child" &lt;&lt; endl; }<br>};<br>void main()<br>{<br> Parent p;<br> Child c;<br> p.func();<br> c.func();<br>}<br>  现在我来解说一下。这段代码中我定义了两个C++类:父类和子类,并且子类是继承自父类的;它们有一个具有相同名称的成员函数func。在main函数中,我分别构造了父类和子类的对象,并调用了它们各自的成员函数func。结果如下:<br>Parent<br>Child<br>  简单说来,这段代码就是子类根据自己的需要改写了func成员函数。而Win32的子类化的原理也与此类似,只不过子类化实际上并没有像C++一样重载哪个函数,而是靠拦截Windows系统中的某些消息来自己进行处理罢了。举例来说,请大家看以下这段简单的窗口回调过程:<br>LRESULT CALLBACK ProcMain(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)<br>{<br> switch (Msg)<br> {<br> case WM_CLOSE:<br> EndDialog(hDlg, 0);<br> break;<br> case WM_DESTROY:<br> PostQuitMessage(0);<br> break;<br> }<br> return 0;<br>}<br>  在这个回调之中,我手动处理了两个消息:在单击了“关闭”按钮(WM_CLOSE)的时候,我将对话框关闭(EndDialog);在对话框销毁(WM_DESTROY)的时候,我向系统消息队列中发送了退出的消息来完成结束工作(PostQuitMessage)。也就是说,如果把WM_CLOSE的响应代码改成:<br> case WM_CLOSE:<br> ShowWindow(hDlg, SW_MINIMIZE);<br> break;<br>  这样一来,这个对话框就会和MSN一样,在单击了“关闭”之后,就会完成最小化的工作了。那么,对于窗口过程已定义好的系统控件,将如何手动响应它的消息呢?<br>  我们可以用函数指针的办法,将我们感兴趣的消息拦截下来,处理完之后再让预定义的窗口过程处理。这个过程大致如下:<br>  WNDPROC OldProc;<br>  OldProc = (WNDPROC)SetWindowsLong(hWnd, GWL_WNDPROC, (LONG)NewProc);<br>  当然,这里的新窗口过程NewProc是预先由你实现好的。上述代码执行以后,系统在处理hWnd的窗口消息时,就会先进入你实现的NewProc回调过程,然后在处理过你感兴趣的消息之后,通过CallWindowProc函数和你预先保存的OldProc再次回到原来的回调过程中完成剩余的工作。<br>  以上就是窗口子类化的原理分析,下面我通过一个实例来实际解说如何对窗口进行子类化。当我们需要一个特殊的Edit来限制浮点数的输入,但是现有的Edit却并不能完成这项工作——因为它只能够单纯的限制大小写或者纯数字。就可以采用“子类化”。</iostream>

  下面我开始按步骤完成对这两个窗口的子类化:
  第一步,在主窗口对话框初始化的时候,保存原有的窗口过程,并设置新的窗口过程。代码如下:
case WM_INITDIALOG:
EditProc = (WNDPROC)SetWindowLong(GetDlgItem(hDlg, IDC_EDIT), GWL_WNDPROC, (LONG)ProcFloat);
StaticProc = (WNDPROC)SetWindowLong(GetDlgItem(hDlg, IDC_ST_HOMEPAGE), GWL_WNDPROC, (LONG)ProcLink);
break;
  第二步,实现浮点编辑框的窗口过程:
LRESULT CALLBACK ProcFloat(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_CHAR && wParam != '.' && (wParam <= '0' || wParam >= '9') && wParam != VK_BACK)
{
MessageBeep(MB_OK);
return 0;
}
else
return CallWindowProc(EditProc, hWnd, Msg, wParam, lParam);
}
  这里需要解释的是,由于控件本身的需求,所以只需要拦截一个消息,就是接收字符的WM_CHAR。当用户输入的字符不是小数点、0~9以及退格键(注意不要少了退格键,否则你将会发现你的编辑框无法删除输入错误的数字)的时候,就发出一声声音以提示输入错误。至于其它的消息,则调用原有的回调函数进行处理。
子类化的限制:因子类化是对已存在的某一窗口产生作用,所以其作用范围只有这一窗,又由于可能不清楚该类怎样使用额外的类和窗口字节,所以不能保证正确使用这些空间存储信息,最后,因窗口已存在,所以新的窗口过程永远不会接收到第一个WM_CREATE消息或其他以前的消息。子类化只适用于改变极少数窗口行为和属性时使用。

分享到:
评论

相关推荐

    走出MFC子类化的迷宫子类化,SUBCLASSWINDOW ,MFC消息机制

    MFC 子类化机制是 Windows 编程中的一种重要技术,允许开发者自定义控件的行为,以满足特定的需求。在这篇文章中,我们将深入探讨 MFC 子类化机制的原理和实现方式,并提供一个实际的示例来演示如何使用子类化机制来...

    走出MFC子类化的迷宫

    本文将详细解释MFC子类化的原理以及如何在MFC环境中实现子类化。 首先,我们需要理解Windows子类化的基本概念。当一个窗口(如控件)被子类化时,我们实际上是将自己的消息处理函数替换掉默认的窗口过程(WndProc)...

    vc++6.0 MFC 窗口子类化

    窗口子类化是Windows编程中的一个技术,通过将一个窗口的窗口过程(WndProc)替换为自定义的处理函数,来扩展或修改标准窗口的行为。在MFC中,我们可以使用`CWnd::SubclassDlgItem`或`CWnd::SubclassWindow`方法来...

    mfc_子类化+双缓冲

    本主题聚焦于"MFC子类化+双缓冲"技术,这是一种解决图形刷新时出现闪烁问题的有效方法。 **子类化(Subclassing)** 子类化是MFC中用于增强控件功能的一种技术。在Windows系统中,每个窗口都有一个与之关联的窗口...

    子类化 超类化 技术分析

    另一方面,"MFC 中子类化技术的应用.pdf"可能深入讨论了MFC中的具体应用实例,比如子类化CDialog以创建自定义对话框,或者子类化CDocument和CView以实现文档视图架构。这些案例可能涵盖了如何处理消息映射、事件响应...

    VC++ MFC 按钮子类化自绘简单范例

    在MFC中,子类化是指将一个标准的控件(如CButton)转换为我们自己的类,这样我们就可以重写其成员函数,以便添加或修改控件的行为。在本例中,我们将CButton子类化为一个新的类,比如CMyButton,以便实现自绘功能。...

    MFC和QT的子类化与常用控件1

    MFC子类化是通过劫持系统默认的窗口过程(WndProc)来实现的,这样可以拦截并处理特定的消息。有以下两种常见的子类化方法: 1. **方法一**:继承相应控件的C++类,例如`CButton`、`CEdit`等,然后重写虚函数,如`...

    我收集的MFC资料,包括子类化,消息映射机制,MFC关键技术,常用数据转化

    `MFC的子类化技术.doc`将深入讲解如何在MFC中进行子类化操作。 2. **消息映射机制**:MFC的消息映射是其核心特性之一,它允许开发者将特定的消息与函数关联起来。当特定的消息到达时,相应的函数会被调用。`分析MFC...

    Edit控件的子类化

    在Windows编程中,子类化(Subclassing)是一种常见的技术,用于扩展或修改标准控件的功能。在本例中,我们关注的是“Edit控件的子类化”,即创建一个自定义的编辑框,使其只能接收数字输入和允许用户按下删除键。这...

    子类化例子

    你可以通过查看和分析这些代码,学习如何在实际项目中应用子类化技术。同时,理解每个函数的作用,例如窗口过程函数是如何处理消息的,以及如何在子类化窗口中添加自定义功能,都是提升编程技能的关键。 总的来说,...

    vc 子类化重绘界面代码

    在VC++(Visual C++)编程环境中,子类化是一种常用的技术,用于扩展或自定义控件和窗口的行为。在标题“vc 子类化重绘界面代码”中,我们聚焦于如何通过子类化来改变Windows应用程序的界面显示。这通常涉及到创建一...

    combox内编辑框和列表框的子类化

    在Windows编程中,`ComboBox`控件是一种常用的用户界面元素,它结合了文本输入框(编辑框)和列表框的功能,允许用户...因此,掌握`ComboBox`的子类化技术对于进行Windows桌面应用程序开发的程序员来说是非常有价值的。

    窗口的子类化与超类化原理及其实例

    而在MFC框架中,所有窗口共享同一个窗口函数,子类化通常涉及修改特定窗口实例的消息处理逻辑,而不是直接改变窗口函数本身。 #### 二、超类化原理 **超类化**是一种更高级的技术,它允许在窗口类级别上修改窗口...

    MFC六大关键技术详解

    MFC的六大关键技术是理解其核心思想的关键,它们分别是:消息映射(Message Mapping)、动态创建(Dynamic Creation)、RTTI(Run-Time Type Information)、文档/视图架构(Document/View Architecture)、对象的...

    A freeware MFC class to support MFC subclassing(19KB)

    MFC子类化是Windows编程中的一个重要概念,它允许我们将一个控件的事件处理功能附加到另一个窗口上。这意味着我们可以创建一个新的类,该类继承自现有的控件类,并添加自定义的功能或行为,而无需直接修改原始控件。...

    利用窗口子类化隐藏系统图标VC源代码

    总结起来,这个代码示例通过窗口子类化技术,利用VC++和MFC库,实现了隐藏Windows窗口系统图标的功能。它可能涉及到处理特定的窗口消息,如`WM_NCCALCSIZE`和`WM_NCPAINT`,并且可能使用DLL注入来实现跨进程的窗口...

    用可视化MFC实现五子棋  

    在本文中,我们将深入探讨如何使用Microsoft Foundation Classes (MFC) 在Visual C++环境中实现一个可视化五子棋游戏。MFC 是微软为Windows应用程序开发提供的一组C++类库,它简化了用户界面的设计和系统资源管理。 ...

    实现图片灰化二值化直方图等效果的MFC程序

    在本文中,我们将深入探讨如何使用...通过这个项目,开发者不仅可以学习到图像处理技术,还能加深对MFC应用程序设计模式的理解。对于想要在Windows平台上开发图形用户界面的软件工程师来说,这样的实践是十分有价值的。

    WINSHOW.rar_win_win32 控件_回调函数_子类化_按钮类

    当是用WIN32API做的话就需要自己来子类化按钮窗口的消息循环了,相信经常编程的朋友都知道,子类化控件要用到SetWindowLong来改变窗口的回调过程,然后在回调窗口内添上自己需要处理的消息即可。因为我们要实现自绘...

Global site tag (gtag.js) - Google Analytics