`
fixopen
  • 浏览: 84105 次
文章分类
社区版块
存档分类
最新评论

什么是所谓的Windows子类化

阅读更多
面向对象大家都清楚。现在OO的主流是基于类的面向对象。子类化故名思义就是定义一个子类,也就是要订制一个类变成一个新类的意思。
不过Windows的子类化不是如此。
首先,我们知道,除了基于类的面向对象以外,还有基于原型(或者叫基于对象)的面向对象。Windows是一个基于对象的OS,它的对象系统更倾向于基于原型的OO。Windows开发的一个核心概念是Window,也就是常说的窗口,所有的一切别的东西都是围绕着这个展开的。一个Windows应用程序,其基本的逻辑框架就是:创建一个窗口,接收系统发给该窗口的消息进行处理。收到结束消息的时候,关掉窗口,程序完蛋。
Window(注意,不是 Windows)相关的一个概念叫作WindowClass,窗口类。窗口类是个啥东西?呵呵,窗口类也是一个对象,具体的可以认为是Window的原型。创建一个WindowClass对象,可以基于该窗口类对象创造多个Window,这些Window在某一方面都是一致的。举个例子,有一个窗口类叫做Button,以这个Button为原型创建的所有Window在某一方面都是一样的。哪一方面呢?某些样式,消息处理例程,菜单等等等等。这些都是 WindowClass里面规定的东西。
那位说了,哦,知道了,基于窗口类原型创建出来Window,这个过程就是子类化。呵呵,广义上说,这是对的,就是特化了一些东西。但Windows子类化有个特殊的含义,它是特指某种行为的。
WindowClass作为一个对象,拥有对象的一切特征,其中包括修改其状态(或属性)的能力。WindowClass有一个属性叫做消息处理器,其实是一个函数指针,指向一个处理发送给它的实例(也就是那些以它为原型的Window)的消息的函数。
所谓的子类化,就是替换这个函数指针成员,用一个新的消息处理函数替代原来的消息处理函数。你或许会觉得奇怪,为什么这个动作叫做子类化?仔细想想其实也不奇怪,不就是修改了WindowClass的行为了么,这个就是子类化了:)
现在我们可以深入的分析一下这个消息处理函数的特征了。
它的职责是处理OS分发给它的各种消息,所以他的典型结构如下:
Handle
{
    switch (msg.name)
    {
    case msgA:
        processMsgA(msg.params);
        break;
    ...
    default:
        windowsSystemDefaultProcess(msg);
        break;
    }
}
对于所有感兴趣的消息,都可以加一个分支处理。于是很多人开始不满了,觉得有坏气味,要重构。重构的方式是把消息和处理做成一个map,这样消息处理就变成:
Handle
{
    if (map[msg.name])
    {
        map[msg.name](msg.params);
        return;
    }
    return windowsSystemDefaultProcess(msg);
}
剩下的问题就是怎么充填这个消息到处理的映射了。
这个充填的方式,MFC采用了宏(其实大多数C++框架都采用了宏),但是宏并不让人满意。采用宏也是历史原因导致的,那时候C++并没有STL这么好用的容器库。有了map,我们再采用宏的方式生成一个映射数组的方式已经过时了。
有了这一步的重构,我们就可以一个函数针对一个消息进行处理了,CWnd就帮我们干了这样一件事。我们要是相对某个特定的消息进行特定的处理,可以给它一个特定的处理函数,放在map中替换原来的处理函数即可。还有另一种方式就是override从CWnd继承下来的消息处理的虚函数,使用C++的动态分派能力进行特定化。
分享到:
评论

相关推荐

    解说Win32的窗口子类代码示例

    在Windows编程中,Win32 API提供了一种强大的机制,允许开发者对已存在的窗口进行定制,这就是所谓的“窗口子类化”(Window Subclassing)。窗口子类化是一种技术,通过它,我们可以替换一个窗口的默认消息处理函数...

    易语言-易语言超级列表框子类化置行列颜色升级

    这就是所谓的"子类化"技术,通过子类化我们可以扩展控件的功能。 子类化是Windows API中的一种技术,允许我们创建一个新窗口类,继承自已有窗口类(如超级列表框),然后替换或添加新的消息处理函数,实现对原有...

    面向对象程序设计基础

    这种方法将数据和操作数据的方法封装在一起,形成所谓的“对象”,从而使得代码更易于理解、维护和重用。本课程主要围绕面向对象方法学展开,结合VC++集成开发环境进行实践教学。 在面向对象编程(OOP)中,有四个...

    多态描述飞行器.zip

    C# 是一种支持面向对象特性的强类型编程语言,由微软开发,广泛应用于Windows平台上的软件开发,包括桌面应用、Web应用和游戏开发等。在C#中,多态性(Polymorphism)是面向对象三大特性(封装、继承、多态)之一,...

    control-rewrite.rar_control_重写控件

    这就是所谓的“控件重写”(Control Overriding)。标题“control-rewrite.rar_control_重写控件”提示我们这是一个关于控件重写的资源包,适用于初学者。描述中提到这个资料已经在Visual Studio 2008环境下测试过,...

    C# WPF和WindForm控件的互操作与IE7样式Tabcontrol的源代码

    在C#编程中,WPF(Windows Presentation Foundation)和WinForms是两种常见的用户界面框架,它们各有优势,但在某些情况下,开发者可能需要在WPF应用中集成WinForms控件,或者反之,这就是所谓的“互操作性”。...

    CStatic链接网站类

    这就是所谓的"CStatic链接网站类"。这个类允许我们在对话框或其他窗口中添加一个静态文本或图像,当用户单击时,它会启动默认的浏览器并导航到预设的URL。 `CStatic`链接网站类通常涉及到以下几个关键知识点: 1. ...

    wxwidgets_test_20191029_1543.tar.gz

    wxWidgets是一个开源的C++库,它允许开发者在多个操作系统平台上创建原生GUI应用程序,包括Windows、Linux和macOS。这个测试项目主要是用来验证和展示如何使用wxWidgets来创建基本的窗口,并在窗口上进行图形绘制。 ...

    Inheritence.zip_Windows编程_C/C++_

    在C++编程中,继承是面向对象编程的一个核心特性,它允许我们创建一个新类(子类或派生类)来扩展已存在的类(基类或超类)。在这个"Windows编程_C/C++_"主题的"Inheritence.zip"压缩包中,我们可以看到一系列关于类...

    WPF涂鸦控件InkCanvas示例

    - 开发者还可以通过子类化InkCanvas并覆盖其部分方法,以实现更复杂的绘图逻辑或特殊功能。 综上所述,InkCanvas是WPF中一个强大的绘图和手写输入控件,能够轻松实现涂鸦、擦除和选择等功能,配合C#编程,可以构建...

    2021-2022计算机二级等级考试试题及答案No.12537.docx

    这确保了在创建子类对象时,父类的构造方法会被自动调用,从而完成必要的初始化工作。 4. **浮点数表示**:计算机内部通常使用阶码和尾数来表示浮点数。这种方法能够有效地表示非常大或非常小的数值,并且保持较高...

    DataGridView+ComboBox

    当需要在`DataGridView`的列中实现可下拉选择的字段时,我们可以将`ComboBox`集成到`DataGridView`中,这就是所谓的“DataGridView+ComboBox”组合。下面我们将详细探讨如何在C#环境下实现这个功能,以及相关的技术...

    testsingletask.rar

    QT框架是Qt公司开发的一款强大的跨平台应用开发框架,它支持Windows、Linux、macOS、Android等操作系统。在QT中,我们有时希望我们的应用程序在系统上只运行一个实例,即当用户再次尝试启动该程序时,而不是启动新的...

    2021-2022计算机二级等级考试试题及答案No.11625.docx

    - **ASP (Active Server Pages)**:一种服务器端脚本环境,适用于 Windows 平台。 - **JSP (JavaServer Pages)**:基于 Java 技术的服务器端开发框架。 - **PHP (Hypertext Preprocessor)**:一种广泛使用的开源...

    C#微软培训资料

    <<page 1>> page begin==================== 目 ...1.1.1 什么是.NET 2000 年 6 月 22 日 不论对 Microsoft 还是对整个 IT 业界都将成为值得纪念的一天 这一天 微软公司正式推出了其下一代...

    CarPlant:在继承kata组成。 这是完整的解决方案

    所谓的“完整解决方案”意味着这个项目提供了一个解决特定问题的全面代码实现,包括所有必要的类和方法,可以作为一个参考或学习资源。 **标签:“C#”** C#是微软开发的一种现代、类型安全的面向对象编程语言,...

    2021-2022计算机二级等级考试试题及答案No.11111.docx

    - 输入掩码主要用于限制或格式化输入数据,确保数据的有效性和一致性。 ### 17. 数组的遍历与求和 **题目**: 执行下列程序段后,正确的结果是? **代码**: ```c++ int k, a[3][3] = {1,2,3,4,5,6,7,8,9}; for (k ...

    PT80-NEAT开发指南v1.1

    NEAT 开 发 指南 文档 适用于 PT80 系列 移动数据终端 版本记录 版本号 版本描述 发布日期 V 1.0 初始版本。 2012-04-12 V1.1 修改前三章内容 2012-09-25 目录 第一章 关于本手册.....................................

Global site tag (gtag.js) - Google Analytics