C++ Builder中动静处理惩罚进程及应用
副标题#e#
C++ Builder作为一种RAD方法的措施开拓东西,其全新的可视化编程情况、面向组件的开拓模式无疑会大大地提高编程效率。它对繁杂的Windows 动静及API作了较全面的封装,编程者在大大都环境下不需剖析Windows动静的细节,只要将心思放在组件的事件处理惩罚函数上即可。然而,究竟Windows操纵系统是一个以动静驱动的系统,运行其上的应用措施,自然无法离开系统之外,因此把握并运用动静处理惩罚,对一些问题的处理惩罚会有事半功倍的结果。
尽量C++ Builder的VCL控件封装了大大都常用的动静,C++ Builder所提供的事件处理惩罚本领也具备了相当水平的完备性,但当处理惩罚C++ Builder 未界说的Windows动静或自界说动静时,把握C++ Builder 的内部动静处理惩罚机制照旧十分须要的。下面,从Windows 操纵系统动静驱念头制开始,进而探讨C++ Builder的VCL控件中动静的封装、通报和处理惩罚机制,最后以新增动静处理惩罚进程的应用实例作为对所讲内容的验证和实践。
一、Windows 动静驱念头制
Windows是以动静驱动的操纵系统,Windows 动静提供了应用措施与应用措施以及应用措施与Windows系统之间举办通讯的手段。
Windows 中有一个系统动静行列,对付每一个正在执行的Windows应用措施,系统为其成立一个“动静行列”,即应用措施行列,用来存放该措施大概建设的各类窗口的动静。应用措施中含有一段称作“动静轮回”的代码,用来从动静行列中检索这些动静并把它们分发到相应的窗口函数中。
动静轮回代码是应用措施中主函数winmain ( )中雷同如下的措施段:
while(GetMessage(&&msg,NULL,NULL,NULL))
{ //从动静行列中取得动静
TranslateMessage(&&msg);
//检索并生成字符动静WM_CHAR
DispatchMessage(&&msg);
//将动静发送给相应的窗口函数
}
由此可见,所谓“动静轮回”,实际是措施轮回。
#p#副标题#e#
Windows 应用措施建设的每个窗口都在系统焦点注册一个相应的窗口函数,窗口函数措施代码形式上是一个庞大的switch 语句,用以处理惩罚由动静轮回发送到该窗口的动静,窗口函数由Windows 回收动静驱动的形式直接挪用,而不是由应用措施显示挪用的,窗口函数处理惩罚完动静后又将节制权返回给Windows。
系统动静行列、应用措施行列、动静轮回和窗口函数之间的干系如图1所示。
二、C++ Builder 中的动静处理惩罚
有了以上Windows 系统动静驱动模式措施设计的认识,下面阐明一下C++ Builder中动静处理惩罚是如何封装、实现的。
Windows 措施框架,包罗一些初始化、动静轮回代码等,在类 Application中封装、实现。每一个用C++ Builder 编写的Windows GUI 应用措施,大部门缺省生成如下代码:
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
//Windows 应用措施主函数
{
try
{
Application-〉Initialize();//作初始化
Application-〉CreateForm(__classid(TForm1), &&Form1);
Application-〉Run();
//个中包括动静轮回
}
catch (Exception &&exception) //破例处理惩罚
{
Application-〉ShowException(&&exception);
}
return 0;
}
对付动静处理惩罚,C++ Builder回收基于控件(component)的措施设计模式,每种控件都担任一套完整的动静派送体系。其实现要领如下: 它为每一种范例的控件都注册一个名为 MainWndProc 的要领函数作为窗口函数,接管“动静轮回”派送来的动静,它是一个非虚拟要领,差池任何特定动静作出格处理惩罚,它仅仅挪用 WndProc 要领函数,并作一些破例处理惩罚。差异控件对动静处理惩罚的定制产生在WndProc 要领中,因为它是一个虚拟要领,每一种控件可以通过包围它来适应出格的环境。WndProc 要领查抄差异的条件,作差异的处理惩罚,从而可以或许滤掉不但愿处理惩罚的各类动静。譬喻:当控件正被拖动时,应忽略键盘事件,所以在Twincontrol 类的WndProc 要领中,有判定当控件不是被拖放状态、才继承通报键盘动静这样成果的代码。最终,WndProc 挪用 Dispatch 要领,它是一个从所用控件的起始祖先Tobject 担任而来的虚拟要领,它确定挪用哪个要领处理惩罚传来的动静。Dispatch 利用动静布局(Tmessage)中的 msg 成员变量确定如那里理惩罚一个特定的动静,假如控件界说了处理惩罚这一动静的函数,则挪用它,不然,就逐级向上追溯,看祖先类是否界说此类的处理惩罚要领,直到起始祖先类(Tobject)。假如都没有界说处理惩罚要领,则挪用缺省的处理惩罚要领(DefaultHandler)。
#p#分页标题#e#
以上是动静在控件中的通报进程,INPRISE公司为利便用户,对动静处理惩罚作了进一步的封装,把常用的动静封装成相应的事件属性,这样编程者完全不消思量动静细节,只要编写事件处理惩罚要领,并给事件属性赋值即可。
三、应用实例
下面以增加新的自界说动静处理惩罚进程为例,对以上所述内容做进一步的说明。
通过以上阐明我们知道,每一条动静的详细处理惩罚进程,是在 Dispatch 中派发完成的,因此增加新的动静, 只要包围虚拟函数 Dispatch 即可。
C++ Builder为了利便地处理惩罚动静,界说了以下三个处理惩罚动静的宏:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(msg,type,meth)
END_MESSAGE_MAP(base)
界说如下:
#define BEGIN_MESSAGE_MAP virtual void __fastcall Dispatch(void 矼essage)
{ switch (((PMessage)Message)-〉Msg)
{
#define VCL_MESSAGE_HANDLER(msg,type,meth)
case msg:
meth(((type)Message)); break;
#define END_MESSAGE_MAP(base) default:
base::Dispatch(Message);
break;
}
}
我们只需在控件类或自界说控件类的public节,依次写入三个宏即可,个中宏VCL_MESSAGE_HANDLER可以按照处理惩罚动静的条数而呈现多次。宏展开后,即生成一个新的Dispatch 函数,它先判定处理惩罚用户界说动静,若是其他动静,则通报至父类的Dispatch 函数处理惩罚,从而完成自界说动静的处理惩罚并担保本来动静处理惩罚体系的完整性。