⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 20000916006.htm

📁 C++Builder教学大全
💻 HTM
字号:
<HTML>

<HEAD>

 

<TITLE>C++ Builder中消息处理过程及应用</TITLE>



<META content="MSHTML 5.00.2314.1000" name=GENERATOR>

</HEAD>

<BODY aLink=#FF0000 bgColor=#ffffff leftMargin=0 link=#187800 topMargin=0 

vLink=#990099>



<div align="center">

  <table width="744" border="0" cellspacing="0" cellpadding="0" height="76">

    <tr> 

      <td> 

        <p align=center><span class=name00><font size="3"><br>

          <b>C++ Builder中消息处理过程及应用</b></font><br>

          </span><span 

            class=Name01><font color=#666666>(作者:张道新) </font></span></p>

        <p align=left> <br>

          <span class=content>  C++ Builder作为一种RAD方式的程序开发工具,其全新的可视化编程环境、面向组件的开发模式无疑会大大地提高编程效率。它对繁杂的Windows 

          消息及API作了较全面的封装,编程者在大多数情况下不需理会Windows消息的细节,只要将心思放在组件的事件处理函数上即可。然而,毕竟Windows操作系统是一个以消息驱动的系统,运行其上的应用程序,自然无法脱离系统之外,因此掌握并运用消息处理,对一些问题的处理会有事半功倍的效果。 

          <br>

          <br>

            尽管C++ Builder的VCL控件封装了大多数常用的消息,C++ Builder所提供的事件处理能力也具备了相当程度的完备性,但当处理C++ 

          Builder 未定义的Windows消息或自定义消息时,掌握C++ Builder 的内部消息处理机制还是十分必要的。下面,从Windows 

          操作系统消息驱动机制开始,进而探讨C++ Builder的VCL控件中消息的封装、传递和处理机制,最后以新增消息处理过程的应用实例作为对所讲内容的验证和实践。 

          <br>

          <br>

          <strong>  一、Windows 消息驱动机制 <br>

          <br>

          </strong>  Windows是以消息驱动的操作系统,Windows 消息提供了应用程序与应用程序以及应用程序与Windows系统之间进行通讯的手段。 

          <br>

          <br>

            Windows 中有一个系统消息队列,对于每一个正在执行的Windows应用程序,系统为其建立一个“消息队列”,即应用程序队列,用来存放该程序可能创建的各种窗口的消息。应用程序中含有一段称作“消息循环”的代码,用来从消息队列中检索这些消息并把它们分发到相应的窗口函数中。 

          <br>

          <br>

            消息循环代码是应用程序中主函数winmain ( )中类似如下的程序段: <br>

          <br>

            while(GetMessage(&amp;&amp;msg,NULL,NULL,NULL)) <br>

          <br>

            { //从消息队列中取得消息 <br>

          <br>

            TranslateMessage(&amp;&amp;msg); <br>

          <br>

            //检索并生成字符消息WM_CHAR <br>

          <br>

            DispatchMessage(&amp;&amp;msg); <br>

          <br>

            //将消息发送给相应的窗口函数 <br>

          <br>

             } <br>

          <br>

            由此可见,所谓“消息循环”,实际是程序循环。 <br>

          <br>

            Windows 应用程序创建的每个窗口都在系统核心注册一个相应的窗口函数,窗口函数程序代码形式上是一个巨大的switch 语句,用以处理由消息循环发送到该窗口的消息,窗口函数由Windows 

          采用消息驱动的形式直接调用,而不是由应用程序显示调用的,窗口函数处理完消息后又将控制权返回给Windows。 <br>

          <br>

            系统消息队列、应用程序队列、消息循环和窗口函数之间的关系如图1所示。 <br>

          <br>

          <strong>  二、C++ Builder 中的消息处理 <br>

          <br>

          </strong>  有了以上Windows 系统消息驱动模式程序设计的认识,下面分析一下C++ Builder中消息处理是如何封装、实现的。 

          <br>

          <br>

             Windows 程序框架,包括一些初始化、消息循环代码等,在类 Application中封装、实现。每一个用C++ Builder 

          编写的Windows GUI 应用程序,大部分缺省生成如下代码: <br>

          <br>

            WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) <br>

          <br>

            //Windows 应用程序主函数 <br>

          <br>

             { <br>

          <br>

                try <br>

          <br>

                { <br>

          <br>

            Application-〉Initialize();//作初始化 <br>

          <br>

            Application-〉CreateForm(__classid(TForm1), &amp;&amp;Form1); <br>

          <br>

            Application-〉Run(); <br>

          <br>

            //其中包含消息循环 <br>

          <br>

             } <br>

          <br>

             catch (Exception &amp;&amp;exception)  //例外处理 <br>

          <br>

             { <br>

          <br>

            Application-〉ShowException(&amp;&amp;exception); <br>

          <br>

             } <br>

          <br>

             return 0; <br>

          <br>

            } <br>

          <br>

            对于消息处理,C++ Builder采用基于控件(component)的程序设计模式,每种控件都继承一套完整的消息派送体系。其实现方法如下: 

          它为每一种类型的控件都注册一个名为 MainWndProc 的方法函数作为窗口函数,接受“消息循环”派送来的消息,它是一个非虚拟方法,不对任何特定消息作特别处理,它仅仅调用 

          WndProc 方法函数,并作一些例外处理。不同控件对消息处理的定制发生在WndProc 方法中,因为它是一个虚拟方法,每一种控件可以通过覆盖它来适应特别的情况。WndProc 

          方法检查不同的条件,作不同的处理,从而能够滤掉不希望处理的各种消息。例如:当控件正被拖动时,应忽略键盘事件,所以在Twincontrol 

          类的WndProc 方法中,有判断当控件不是被拖放状态、才继续传递键盘消息这样功能的代码。最终,WndProc 调用 Dispatch 

          方法,它是一个从所用控件的起始祖先Tobject 继承而来的虚拟方法,它确定调用哪个方法处理传来的消息。Dispatch 使用消息结构(Tmessage)中的 

          msg 成员变量确定如何处理一个特定的消息,如果控件定义了处理这一消息的函数,则调用它,否则,就逐级向上追溯,看祖先类是否定义此类的处理方法,直到起始祖先类(Tobject)。如果都没有定义处理方法,则调用缺省的处理方法(DefaultHandler)。 

          <br>

          <br>

            以上是消息在控件中的传递过程,INPRISE公司为方便用户,对消息处理作了进一步的封装,把常用的消息封装成相应的事件属性,这样编程者完全不用考虑消息细节,只要编写事件处理方法,并给事件属性赋值即可。 

          <br>

          <br>

          

          <strong>  三、应用实例 <br>

          <br>

          </strong>  下面以增加新的自定义消息处理过程为例,对以上所述内容做进一步的说明。 <br>

          <br>

            通过以上分析我们知道,每一条消息的具体处理过程,是在 Dispatch 中派发完成的,因此增加新的消息, 只要覆盖虚拟函数 Dispatch 

          即可。 <br>

          <br>

            C++ Builder为了方便地处理消息,定义了以下三个处理消息的宏: <br>

          <br>

            BEGIN_MESSAGE_MAP <br>

          <br>

            VCL_MESSAGE_HANDLER(msg,type,meth) <br>

          <br>

            END_MESSAGE_MAP(base) <br>

          <br>

            定义如下: <br>

          <br>

            #define BEGIN_MESSAGE_MAP virtual void __fastcall Dispatch(void 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -