深入VCL 理解BCB的消息机制
- 格式:pdf
- 大小:47.09 KB
- 文档页数:27
MFC(Microsoft Foundation Classes)是一种用于开发Windows应用程序的C++类库,它建立在Win32 API之上,并提供了更高层次的抽象和封装。
在MFC中,消息机制是实现应用程序与用户交互和事件处理的基础。
MFC消息机制的原理如下:1.消息映射表:在MFC应用程序中,每个窗口类(如对话框类、视图类等)通常都有一个消息映射表(message map),用于将消息与相应的处理函数关联起来。
消息映射表是一个静态数据结构,通过DECLARE_MESSAGE_MAP宏进行声明,并在类的实现文件中使用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏定义映射表的内容。
2.消息处理函数:每个消息映射表项将消息的ID(或者命令ID)与相应的消息处理函数绑定在一起。
消息处理函数是成员函数,由开发人员根据需要自行定义。
当相应的消息被触发时,系统会自动调用与该消息对应的处理函数。
3.消息循环:MFC应用程序在运行时通过消息循环(message loop)不断接收和分发消息。
消息循环负责从操作系统获取消息,并将消息派发给目标窗口的消息处理函数进行处理。
消息循环可以使用Run函数或AfxGetApp()->Run函数启动。
4.分发消息:当系统从消息队列中获取到一个消息后,会根据消息的目标窗口通过HWND来查找对应的CWnd对象,并调用该窗口的响应函数(如PreTranslateMessage、OnCmdMsg等)进行消息处理。
如果消息在目标窗口的消息映射表中找到了对应的处理函数,则将该消息转发给对应的处理函数进行处理。
5.消息处理:消息处理函数执行相应的逻辑,可以进行界面更新、控件操作、数据处理等操作。
处理函数的返回值通常是布尔型,表示是否终止消息的传递。
通过这种消息机制,MFC应用程序可以实现用户交互和事件处理的功能,使开发人员可以方便地处理窗口消息,响应用户操作,以及完成界面和数据之间的交互。
mfc消息机制
MFC(Microsoft Foundation Class)是微软开发的一种面向对象的C++框架,用于Windows操作系统的应用程序开发。
MFC消息机制是MFC框架的核心之一,其基本原理是在窗口、控件等对象之间传递消息,以便处理事件和交互。
具体而言,MFC消息机制包括以下几个方面:1.消息循环:MFC使用一个消息循环来接受和处理Windows操作系统发送的Windows消息,处理完消息后将处理结果反馈给Windows操作系统。
2.消息映射:MFC中的控件和窗口都有一个关联的消息映射表,用于将Windows消息映射到应用程序代码中的相应处理函数上。
当某个控件或窗口收到消息后,根据消息类型在相应的消息映射表中查找对应的消息处理函数,并调用相应的处理函数处理消息。
3.消息类型:MFC处理的Windows消息类型包括键盘和鼠标消息、定时器消息、系统负载消息、窗口大小变化消息等等,具体的消息类型可以在MFC框架的文档中查找。
4.消息处理函数:MFC中的消息处理函数是C++成员函数,定义为afx_msg 修饰的函数,Windows消息处理函数命名时需要遵循一定的命名规则,例如OnPaint()函数用于处理绘图事件。
需要注意的是,MFC消息机制是针对Windows操作系统设计的,其他操作系统可能具有不同的消息机制。
此外,MFC框架已经不是微软推荐的最先进的应用程序开发框架,已经逐渐被其他框架和技术所取代,例如.NET Framework,WPF,UWP等。
BCB控件制作和消息处理1 前言作为和delphi类似的rad(rapid application development)工具,c++ builder的强大功能不仅体现在数据库开发方面,也凸现于应用程序开发上(令人称绝的是这两方面结合得非常好)。
仅就应用程序而言,要真正体现c++ builder的优势,开发出高质量的软件,则在拖拉拽放之外,尚需用到一些进阶技术。
如消息处理、dll、ole、线程、sdk编程。
c++ builder 在这些方面都或多或少有独到的优势。
此外,可以方便地制作自定义控件,也是c++ builder 的一大特色和高级功能。
本文将通过制作一个标题棒在窗口左边的对话框控件,来示范一些c++ builder中关于控件制作和消息处理的概念,同时涉及到一点sdk编程。
我们将要制作的是一个对话框,就如同opendialog等一样,一调用其execute()方法,就弹出一个窗口。
这个窗口的标题棒位于左方,绿色,文字走向为由下而上的90度字形,其功能和一般的标题棒相同,可以將鼠标移至该处来移动该窗口。
首先来完成这个窗口,然后用它来制作对话框控件。
2 利用wm_nchittest消息制作竖直标题的窗口.wm_nchittest消息c++builder将某些windows消息封装于事件(event)中,但无法囊括所有消息,如wm_nc**** 系列消息。
wm_nchittest消息发生于游标(cursor)移动或鼠标按下、释放时,返回值指示目前游标所在位置,如返回hthscroll表示处于水平滚动条内,返回htcaption表示处于标题棒内(参见win32 sdk help)。
其参数xpos、ypos分别表示游标的x、y坐标(相对于屏幕左上角),分别对应于lparam的低字和高字。
如果拦截wm_nchittest消息,使得当鼠标在窗口左边按下时,人为地将返回值设为htcaption,则系统将以为是在标题棒内,于是将可以移动窗口,完成了标题棒的功能,至于颜色和文字,则与消息无关,将在下面叙述其原理。
C语消息机制1. 介绍C语言是一种通用的高级编程语言,广泛应用于系统开发和嵌入式设备。
C语言提供了丰富的库函数和特性,使得开发者能够更加灵活地控制程序的执行流程和数据传递。
消息机制是C语言中一种常用的编程技术,用于实现不同模块之间的通信和协作。
2. 消息机制的基本概念消息机制是一种通过消息传递来实现模块之间通信的技术。
在消息机制中,模块之间通过发送和接收消息来实现数据的传递和交换。
消息机制可以用于解耦模块之间的依赖关系,提高系统的可扩展性和可维护性。
消息机制的基本概念包括消息队列、消息发送和消息接收。
消息队列是一个存储消息的缓冲区,用于存放待发送和待接收的消息。
消息发送是将消息放入消息队列的过程,而消息接收则是从消息队列中取出消息的过程。
3. 消息机制的实现方式在C语言中,消息机制可以通过多种方式来实现,常见的方式包括共享内存、信号量和管道等。
3.1 共享内存共享内存是一种在多个进程之间共享数据的机制。
在消息机制中,可以使用共享内存来实现消息队列。
每个进程可以通过读写共享内存的方式来发送和接收消息。
共享内存的优点是速度快,但需要注意进程间的同步和互斥问题。
3.2 信号量信号量是一种用于进程间同步和互斥的机制。
在消息机制中,可以使用信号量来实现消息队列的同步和互斥。
每个进程可以通过对信号量进行P操作和V操作来发送和接收消息。
信号量的优点是简单易用,但需要注意死锁和竞态条件的问题。
3.3 管道管道是一种用于进程间通信的机制。
在消息机制中,可以使用管道来实现消息队列。
每个进程可以通过写入和读取管道的方式来发送和接收消息。
管道的优点是简单高效,但只能用于有亲缘关系的进程间通信。
4. 消息机制的应用场景消息机制在实际的软件开发中有广泛的应用场景,下面介绍几个常见的应用场景。
4.1 进程间通信消息机制可以用于实现不同进程之间的通信。
通过消息机制,不同进程可以通过发送和接收消息来实现数据的传递和共享。
消息机制可以解决进程间的同步和互斥问题,提高系统的并发性能。
vc消息机制
VC消息机制是一种在Windows编程中使用的消息传递机制。
它允许应用程序通过发送和接收消息来通信,这些消息可以是自定义的,也可以是预定义的。
VC消息机制的核心是消息循环。
在Windows应用程序中,消息循环是一个无限循环,负责接收并处理来自操作系统的消息。
当应用程序启动时,它会进入消息循环,等待消息的到来。
当接收到消息时,应用程序会根据消息的类型和内容执行相应的操作。
VC消息机制主要包括以下几个步骤:
1.发送消息:应用程序可以通过发送消息来通知其他窗口或线程。
发送消息可以通过PostMessage或SendMessage函数实现。
PostMessage函数将消息放入目标窗口的消息队列中,而SendMessage函数会直接将消息发送给目标窗口。
2.接收消息:应用程序通过消息循环接收来自操作系统的消息。
当接收到消息时,应用程序会根据消息的类型和内容执行相应的操作。
3.处理消息:应用程序可以对接收到的消息进行处理。
处理消息的方式取决于消息的类型和内容。
例如,当接收到鼠标点击事件时,应用程序可能会更新鼠标指针的位置或触发鼠标点击事件的处理函数。
4.结束消息循环:当应用程序处理完所有消息后,它会结束消息循环并退出。
VC消息机制是一种非常灵活和强大的机制,它允许应用程序通
过发送和接收消息来通信,从而实现各种交互和功能。
Delphi,一个非常优秀的开发工具,拥有强大的可视化开发环境、面向组件的快速开发模式、优秀的VCL 类库、快速的代码编译器、强大的数据库和WEB开发能力、还有众多的第三方控件支持...(此处省略x千字,既然大家都知道了,不浪费口水了 ^_^)说到VCL的优秀就不能不提到其对Windows消息及API的较全面和完美的封装,正因为如此开发者在大多数情况下甚至不需理会Windows消息处理的细节,而只需要写几行事件驱动代码即可!但如果做为开发人员你还是想对此做些了解的话,那么就继续,通过VCL代码本身来体会VCL中的消息处理机制。
(以下代码取自Delphi 6)说到VCL中的消息处理就不能不提到TApplication,Windows会为每一个当前运行的程序建立一个消息队列,用来完成用户与程序的交互,正是通过Application完成了对Windows消息的集中处理!首先通过Application.Run进入消息循环进行消息的处理,其中调用了HandleMessage。
procedure TApplication.HandleMessage;varMsg: TMsg;beginif not ProcessMessage(Msg) then Idle(Msg);//这里先调用ProcessMessage处理,返回值为False调用Idle,就是在空闲时,即消息队列中无消息等待处理时调用Idle。
end;function TApplication.ProcessMessage(var Msg: TMsg): Boolean;varHandled: Boolean;beginResult := False;if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then//查询消息队列中有无消息等待处理,参数PM_REMOVE 使消息在处理完后会被删除。
beginResult := True;if Msg.Message <> WM_QUIT then//如果是WM_QUIT,终止进程,否则执行下面的代码beginHandled := False;if Assigned(FOnMessage) then FOnMessage(Msg, Handled);if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) andnot IsKeyMsg(Msg) and not IsDlgMsg(Msg) thenbeginTranslateMessage(Msg);//将记录Msg传递给Windows进行转换DispatchMessage(Msg);//将记录Msg回传给Windowsend;endelseFTerminate := True;end;end;然后程序中的各个VCL对象又是如何接收到Windows消息的呢?这还要从窗体的创建开始!首先找到TWinControl.CreateWnd中的Windows.RegisterClass(WindowClass)//调用RegisterClass注册一个窗体类向上看WindowClass.lpfnWndProc := @InitWndProc;//这里指定了窗口的消息处理函数的指针为@InitWndProc!再找到function InitWndProc(HWindow: HWnd; Message, WParam, LParam: Longint): Longint;发现了CreationControl.FHandle := HWindow;SetWindowLong(HWindow, GWL_WNDPROC,Longint(CreationControl.FObjectInstance));没有?原来InitWndProc初次被调用时候,又使用API函数SetWindowLong指定处理消息的窗口过程为FObjectInstance。
mfc 信息机制MFC信息机制MFC(Microsoft Foundation Class)是微软公司推出的一套用于Windows操作系统的C++类库,它为开发者提供了丰富的工具和组件,用于快速构建Windows应用程序。
在MFC中,信息机制是其重要特性之一,它提供了一种方便的方式来管理和传递应用程序中的消息。
一、消息机制的基本概念在MFC中,消息是指应用程序中发生的各种事件,比如鼠标点击、键盘输入、窗口关闭等。
消息机制是指MFC框架中的一套机制,用于处理和分发这些消息。
消息的处理过程包括两个关键组件:消息映射和消息处理函数。
1. 消息映射消息映射是指将消息和消息处理函数进行关联的过程。
通过在类的消息映射表中添加相应的消息和处理函数的映射关系,可以告诉MFC框架在收到某个消息时应该调用哪个函数进行处理。
消息映射表一般定义在类的声明中,使用宏来声明消息映射表的内容。
2. 消息处理函数消息处理函数是指用于处理特定消息的函数。
当MFC框架收到某个消息时,会根据消息映射表中的映射关系调用相应的消息处理函数。
消息处理函数可以是类的成员函数,也可以是全局函数,具体取决于消息映射表中的声明方式。
二、消息机制的应用场景消息机制在MFC中广泛应用于用户界面的交互和事件响应。
通过消息机制,开发者可以方便地处理用户的操作和系统的事件,实现各种功能和交互效果。
1. UI事件响应在MFC应用程序中,用户通过与界面上的控件进行交互来触发各种事件,比如按钮点击、菜单选择等。
通过消息机制,我们可以将这些事件与相应的处理函数进行关联,当用户触发某个事件时,可以执行相应的处理逻辑。
2. 窗口消息处理MFC中的窗口是指用户界面上的各种窗口元素,比如对话框、窗口、视图等。
窗口消息是指与窗口相关的各种事件,比如窗口创建、大小改变、关闭等。
通过消息机制,我们可以对窗口消息进行处理,实现窗口的初始化、布局、关闭等功能。
3. 自定义消息除了系统定义的消息类型,MFC还支持自定义消息。
深度解析VC中的消息传递机制深度解析VC中的消息传递机制摘要:Windows编程和Dos编程,一个很大的区别就是,Windows编程是事件驱动,消息传递的。
所以,要学好Windows编程,必须对消息机制有一个清楚的认识,本文希望能够对消息的传递做一个全面的分析。
一、什么是消息?消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉。
一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向Windows发出一个通知,告诉应用程序某个事情发生了。
例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。
消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。
例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。
这个记录类型叫做MSG,MSG 含有来自windows应用程序消息队列的消息信息,它在Windows中声明如下:typedef struct tagMsgHWND hwnd;//接受该消息的窗口句柄UINT message;//消息常量标识符,也就是我们通常所说的消息号WPARAM wParam;//32位消息的特定附加信息,确切含义依赖于消息值LPARAM lParam;//32位消息的特定附加信息,确切含义依赖于消息值DWORD time;//消息创建时的时间POINT pt;//消息创建时的鼠标/光标在屏幕坐标系中的位置}MSG;消息可以由系统或者应用程序产生。
系统在发生输入事件时产生消息。
举个例子,当用户敲键,移动鼠标或者单击控件。
系统也产生消息以响应由应用程序带来的变化,比如应用程序改变系统字体,改变窗体大小。
应用程序可以产生消息使窗体执行任务,或者与其他应用程序中的窗口通讯。
二、消息中有什么?我们给出了上面的注释,是不是会对消息结构有了一个比较清楚的认识?如果还没有,那么我们再试着给出下面的解释:hwnd 32位的窗口句柄。
C++Builder(BCB)是什么?C++ Builder是基于可视组件技术和C++语⾔的快速应⽤程序开发⼯具。
C++ Builder的前⾝是Borland C++,⽽Borland C++最早是Turbo C,在DOS界⾯编程的年代,对于每⼀个⼯科学⽣,⼏乎是⽆⼈不知。
学习C++ Builder最常⽤的版本是C++ Builder 6.0,C++ Builder 2010等,最新的版本(RAD Studio)还⽀持iOS、安卓等多平台软件的开发。
Windows是图形⽤户界⾯(Graphical User Interface)操作系统,标准的Windows应⽤程序也是图形⽤户界⾯的。
传统上,SDK⽅式开发Windows应⽤程序的GUI界⾯是⼀个很繁琐的⼯作,界⾯相关和消息处理的代码量甚⾄占到项⽬总代码量的⼀半以上,⽽且和业务逻辑代码是混杂在⼀起的,程序难以扩展、重⽤和维护。
C++ Builder是真正的可视化的开发⼯具。
C++ Builder可以⽤⿏标拖拉控件加上设置属性轻松地“设计”出⼀个程序的图形⽤户界⾯,利⽤可视的组件/控件像“搭积⽊”⼀样,以“所见即所得”的⽅式搭建应⽤程序的界⾯,这也是C++ Builder这个名字中Builder的概念。
这样,只需要⽤C++语⾔编写业务逻辑代码,类似于DOS下⽂本界⾯编程,只要专注于实现业务逻辑功能就可以了,代码⾮常简洁。
数据的输⼊和表现,都在图形⽤户界⾯,⾮常直观、易⽤。
这就是RAD开发(Rapid Application Development,快速应⽤程序开发)。
VCL是Visual Component Library的缩写,即可视组件库,它是Delphi和C++ Builder编程语⾔的基本类库。
VCL以组件化、可视化为设计⽅向,是新⼀代的应⽤程序框架(Framework)。
VCL组件是对Win32 API和Windows消息的封装,将繁杂的API调⽤和琐碎的细节以及复杂的消息处理过程封装为使⽤简便的类接⼝——属性、⽅法和事件,具有封装纯粹、可扩展性强、使⽤⽅便等特点。
下面几节将分析MFC的消息机制的实现原理和消息处理的过程。
为此,首先要分析ClassWizard实现消息映射的内幕,然后讨论MFC 的窗口过程,分析MFC窗口过程是如何实现消息处理的。
1.消息映射的定义和实现1.MFC处理的三类消息根据处理函数和处理过程的不同,MFC主要处理三类消息:∙Windows消息,前缀以“WM_”打头,WM_COMMAND例外。
Windows消息直接送给MFC窗口过程处理,窗口过程调用对应的消息处理函数。
一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC窗口类的成员函数。
∙控制通知消息,是控制子窗口送给父窗口的WM_COMMAND通知消息。
窗口过程调用对应的消息处理函数。
一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC 窗口类的成员函数。
需要指出的是,Win32使用新的WM_NOFITY来处理复杂的通知消息。
WM_COMMAND类型的通知消息仅仅能传递一个控制窗口句柄(lparam)、控制窗ID和通知代码(wparam)。
WM_NOTIFY能传递任意复杂的信息。
∙命令消息,这是来自菜单、工具条按钮、加速键等用户接口对象的WM_COMMAND通知消息,属于应用程序自己定义的消息。
通过消息映射机制,MFC框架把命令按一定的路径分发给多种类型的对象(具备消息处理能力)处理,如文档、窗口、应用程序、文档模板等对象。
能处理消息映射的类必须从CCmdTarget类派生。
在讨论了消息的分类之后,应该是讨论各类消息如何处理的时候了。
但是,要知道怎么处理消息,首先要知道如何映射消息。
1.MFC消息映射的实现方法MFC使用ClassWizard帮助实现消息映射,它在源码中添加一些消息映射的内容,并声明和实现消息处理函数。
现在来分析这些被添加的内容。
在类的定义(头文件)里,它增加了消息处理函数声明,并添加一行声明消息映射的宏DECLARE_MESSAGE_MAP。
深入VCL 理解BCB的消息机制引子本文所谈及的技术内容都来自于Internet的公开信息。
由CKER在闲暇之际整理后,贴出来以飴网友,姑且妄称原创。
『每次在国外网站上找到精彩文章的时候,心中都会暗自叹息为什么在中文网站难以觅得这类文章呢?其实原因大家都明白。
』时至今日,学习Windows编程的兄弟们都知道消息机制的重要性。
所以理解消息机制也成了不可或缺的功课。
大家都知道,Borland的C++ Builder以及Delphi的核心是VCL。
作为Win32平台上的开发工具,封装Windows的消息机制当然也是必不可少的。
那么,在C++ Builder中处理消息的方法有哪些呢?它们之间的区别又在哪里?如果您很清楚这些,呵呵,对不起啦,请关掉这个窗口。
如果不清楚那就和我一起深入VCL的源码看个究竟吧。
『注:BCB只有Professional和Enterprise版本才带有VCL源码。
当然,大伙的版本都有源码的。
我没猜错吧:-)<CKER用的是BCB5>』方法1。
使用消息映射(Message Map)重载TObject的Dispatch虚成员函数这个方法大家用的很多。
形式如下BEGIN_MESSAGE_MAPVCL_MESSAGE_HANDLER( … …)END_MESSAGE_MAP( …)但这几句话实在太突兀,C++标准中没有这样的定义。
不用讲,这显然又是宏定义。
它们到底怎么来的呢?CKER第一次见到它们的时候,百思不得其解。
嘿嘿,不深入VCL,怎么可能理解?在\Borland\CBuilder5\Include\Vcl找到sysmac.h,其中有如下的预编译宏定义:#define BEGIN_MESSAGE_MAP virtual void __fastcall Dispatch(void*Message) \{ \switch (((PMessage)Message)->Msg) \{#define VCL_MESSAGE_HANDLER(msg,type,meth) \case msg: \meth(*((type *)Message)); \break;// NOTE: ATL defines a MESSAGE_HANDLER macro which conflicts with VCL's macro. The// VCL macro has been renamed to VCL_MESSAGE_HANDLER. If you are not using ATL,// MESSAGE_HANDLER is defined as in previous versions of BCB.file://#if !defined(USING_ATL) && !defined(USING_ATLVCL)&& !defined(INC_ATL_HEADERS)#define MESSAGE_HANDLER VCL_MESSAGE_HANDLER#endif // ATL_COMPAT#define END_MESSAGE_MAP(base)default: \base::Dispatch(Message); \break; \} \}这样对如下的例子:BEGIN_MESSAGE_MAPVCL_MESSAGE_HANDLER(WM_PAINT,TMessage,OnPaint)END_MESSAGE_MAP(TForm1)在预编译时,就被展开成如下的代码virtual void __fastcall Dispatch(void *Message){switch (((PMessage)Message)->Msg){case WM_PAINT:OnPaint(*((TMessage *)Message)); //消息响应句柄,也就是响应消息的成员函数,在Form1中定义break;default:Form1::Dispatch(Message);break;}}这样就很顺眼了,对吧。
对这种方法有两点要解释一下:1。
virtual void __fastcall Dispatch(void *Message) 这个虚方法的定义最早可以在TObject的定义中找到。
打开BCB 的帮助,查找TForm的Method(方法),你会发现这里很清楚的写着Dispatch方法继承自TObject。
如果您关心VCL的继承机制的话,您会发现TObject是所有VCL对象的基类。
TObject的抽象凝聚了Borland的工程师们的心血。
如果有兴趣。
您应该好好查看一下TObject的定义。
很显然,所有Tobject的子类都可以重载基类的Dispatch方法,来实现自己的消息调用。
如果Dispatch方法找不到此消息的定义,会将此消息交由TObject::DefaultHandler方法来处理。
抽象基类TObject的DefaultHandler 方法实际上是空的。
同样要由继承子类重载实现它们自己的消息处理过程。
2。
很多时候,我见到的第二行是这样写的:MESSAGE_HANDLER(WM_PAINT,TMessage,OnPaint)在这里,您可以很清楚的看到几行注解,意思是ATL中同样包含了一个MESSAGE_HANDLER的宏定义,这与VCL发生了冲突。
为了解决这个问题,Borland改用VCL_MESSAGE_HANDLER这样的写法。
当您没有使用ATL的时候,MESSAGE_HANDLER将转换成VCL_MESSAGE_HANDLER。
但如果您使用了ATL的话,就会有问题。
所以我建议您始终使用VCL_MESSAGE_HANDLER的写法,以免出现问题。
方法2。
重载TControl的WndProc方法还是先谈谈VCL的继承策略。
VCL中的继承链的顶部是TObject基类。
一切的VCL组件和对象都继承自TObject。
打开BCB帮助查看TControl的继承关系:TObject->TPersistent->TComponent->TControl呵呵,原来TControl是从TPersistent类的子类TComponent类继承而来的。
TPersistent抽象基类具有使用流stream来存取类的属性的能力。
TComponent类则是所有VCL组件的父类。
这就是所有的VCL组件包括您的自定义组件可以使用dfm文件存取属性的原因『当然要是TPersistent的子类,我想您很少需要直接从TObject类来派生您的自定义组件吧』。
TControl类的重要性并不亚于它的父类们。
在BCB的继承关系中,TControl 类的是所有VCL可视化组件的父类。
实际上就是控件的意思吧。
所谓可视化是指您可以在运行期间看到和操纵的控件。
这类控件所具有的一些基本属性和方法都在TControl类中进行定义。
TControl的实现在\Borland\CBuilder5\Source\Vcl\control.pas中可以找到。
『可能会有朋友问你怎么知道在那里?使用BCB提供的Search -> Find in files很容易找到。
或者使用第三方插件的grep功能。
』好了,进入VCL的源码吧。
说到这里免不了要抱怨一下Borland。
哎,为什么要用pascal实现这一切.....:-(TControl继承但并没有重写TObject的Dispatch()方法。
反而提供了一个新的方法就是xycleo提到的WndProc()。
一起来看看Borland的工程师们是怎么写的吧。
procedure TControl.WndProc(var Message: TMessage);varForm: TCustomForm;begin//由拥有control的窗体来处理设计期间的消息if(csDesigning in ComponentState) thenbeginForm := GetParentForm(Self);if(Form <> nil) and(Form.Designer <> nil) andForm.Designer.IsDesignMsg(Self, Message) then Exit;end//如果需要,键盘消息交由拥有control的窗体来处理else if(Message.Msg >= WM_KEYFIRST) and(Message.Msg <= WM_KEYLAST) thenbeginForm := GetParentForm(Self);if(Form <> nil) and Form.WantChildKey(Self, Message) then Exit; end//处理鼠标消息else if(Message.Msg >= WM_MOUSEFIRST) and(Message.Msg <= WM_MOUSELAST) thenbeginif not(csDoubleClicks in ControlStyle) thencase Message.Msg ofWM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK,WM_MBUTTONDBLCLK:Dec(Message.Msg, WM_LBUTTONDBLCLK -WM_LBUTTONDOWN);end;case Message.Msg ofWM_MOUSEMOVE: Application.HintMouseMessage(Self, Message);WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:beginif FDragMode = dmAutomatic thenbeginBeginAutoDrag;Exit;end;Include(FControlState, csLButtonDown);end;WM_LBUTTONUP:Exclude(FControlState, csLButtonDown);end;end// 下面一行有点特别。
如果您仔细的话会看到这个消息是CM_VISIBLECHANGED.// 而不是我们熟悉的WM_开头的标准Windows消息.// 尽管Borland没有在它的帮助中提到有这一类的CM消息存在。
但很显然这是BCB的// 自定义消息。
呵呵,如果您对此有兴趣可以在VCL源码中查找相关的内容。
一定会有不小的收获。
else if Message.Msg = CM_VISIBLECHANGED thenwith Message doSendDockNotification(Msg, WParam, LParam);// 最后调用dispatch方法。