Effective BCB Form Program(1) ——窗体事件驱动链引发程序错误分析

原创 2001年11月05日 23:06:00

Effective BCB Form Program

——窗体事件驱动链引发程序错误分析

 

BCB中采用的类库是VCL,其编程框架是事件驱动的,类似于VB。我在开发过程中发现,如果不对BCB的事件驱动链进行分析,写的程序会带有很多的错误,健壮性很成问题,而且调试很麻烦。

我发现程序中的很多错误都来源于C++的指针操作。在程序中用new的方法创建了一个对象,然后delete这个对象之后,如果此时还有其它指针指向这个对象,访问此对象信息的代码必定会引发异常。这在C++中是常识性的问题。但这个问题在BCB这类事件驱动的开发环境中就复杂化了。由于事件模型其实是对Windows消息循环机制的一个封装,而Windows中一个消息可能会引发一连串的其他消息,所以,事件之间也是相互引发的,形成一个事件驱动的链条。

BCB这类RAD的开发环境中,窗体(Form)是最核心的组件,窗体的事件模型也是程序中最需要分析的。

我在BCB5中设计了几种典型情况,针对BCB提供的事件模型,绘出了BCB中的事件驱动链。由于WM_PAINT消息的反复激发,所以我有意识地屏蔽掉了对这一消息的响应事件OnPaint。我发现大多数错误就发生成窗体的生成与销毁过程中,其主要的原因就是程序员选错了事件,将代码放错了地方。所以,我重点分析了工程中窗体的创建和销毁过程中的事件驱动链。

 

先对BCB的工程文件(BPR)进行分析:

 

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

        try

        {

                 Application->Initialize();

                 Application->CreateForm(__classid(TForm1), &Form1);

                 Application->Run();

        }

        catch (Exception &exception)

        {

                 Application->ShowException(&exception);

        }

        return 0;

}

 

WinMainBCB工程的入口点,Initialize()一句完成程序的初始化工作,CreateForm()一句完成窗体的创建工作(在此引发一系列的事件),Run()一句则进入了消息循环,此时事件主要是用户操作引发的(当然也有定时器等操作系统引发的事件)。

Catch()一句保证应用程序不会引起操作系统的崩溃。但这也是无数的BCBDelphi程序会引发“XXX内存读写错误”信息的根源所在。正是为了提高BCB程序的健壮性,我才进行了这个实验,其中比较枯燥,不想看记录的人可以直接去看结论部分。

实验记录:

一、由BCB自动创建的Form的事件驱动链

实验一. 工程中只有一个主窗体Form1

当窗体中只有一个主窗体(Form1)时,程序运行事件的发生次序如下:

创建

Form1构造函数àOnCreate()  //到此窗体创建完毕,以下进入窗体的显示过程

àOnShow()àOnActivate()àOnCanResize()àOnConstrainedResize()àOnResize()

窗体显示完毕,以下进入消息循环,等待用户输入.

关闭

关闭主窗体Form1:

OnCloseQuery()àOnClose()  //到此退出消息循环

àOnHide()àOnDestory()à~Form1()析构函数

 

显然,一个窗体要先隐藏,再销毁,最后再调用析构函数

另外:OnShow()à……àOnResize()这一事件链在各种情况中始终不变,下面的记录中我就以……代表这些不变的事件链。

实验二:工程中有两个窗体,Form1为主窗体,Form2为普通窗体

当工程中有两个窗体,Form1为主窗体,Form2为普通窗体,事件链如下:

创建

Form1构造函数à OnCreate() //到此窗体Form1创建完毕,开始创建Form2

à Form2构造函数

//以下进入Form1的显示过程

àOnShow()à……àOnResize()

 

除非在代码中指定,缺省情况下Form2只处于加载状态,不会显示,Form2中的OnCreate()等事件代码不会运行。

关闭

关闭时,Form2处于隐藏或显示状态均一样:

Form1OnCloseQuery()àOnClose()  //到此退出工程消息循环,以下销毁Form2

àForm2析构函数àForm1 OnHide()àForm1OnDestory()à~Form1()析构函数

 

值得注意的是,这时,Form2OnDestory()没有被执行,对应地,当它创建时,Form2OnCreate()也没有执行!

实验三:工程中有两个窗体,Form1为主窗体,Form2继承自Form1

BCB中,可以很方便地继承某个窗体,这是BCB的一个非常好用的功能。

创建

Form1构造函数à OnCreate() //到此窗体Form1创建完毕,开始创建Form2

àForm2OnCreate()àForm1的构造函数àForm2的构造函数  //以下进入Form1的显示过程,同单窗体工程一样àOnShow()à……àOnResize()

 

值得注意的是:Form2OnCreate()函数居然先于Form2的构造函数运行!

关闭

1Form2为隐藏状态,

Form1OnCloseQuery()àOnClose()  //到此退出工程消息循环,以下销毁Form2

àForm2析构函数àForm1的析构函数àForm2OnDestory()àForm1 OnHide()àForm1OnDestory()àForm1的析构函数

 

注意:Form1的析构函数被执行了两次!

 

2Form2为显示状态

Form1OnCloseQuery()àOnClose()  //到此退出工程消息循环,以下销毁Form2

àForm2OnHide()àForm2的析构函数à Form1的析构函数à Form2OnDestory()àForm1 OnHide()àForm1OnDestory()àForm1的析构函数

 

注意:Form1的析构函数被执行了两次!

两种情况对比,可以发现只多了一个Form2的隐藏过程.

C#处理WindowForm程序中未捕获的异常

经常有客户抱怨程序遇到错误的时候程序就退出了,甚至来不及保存窗体的输入数据,如果是普通的搜索界面也就罢了,但如果客户是呼叫中心,问题就严重了.按道理,我们的程序员应该处理所有的异常,但有事实上做到的很...
  • iuhiqnehc
  • iuhiqnehc
  • 2013年06月25日 14:25
  • 1079

C#窗体之间传递消息和事件

C# WinForm编程中,你是否遇到过这样的问题,在主窗口Form1中点击按钮,弹出一个子窗口Form2,你希望在Form2中调用Form1的函数,改变Form1的显示,却发现Form1不听话,达不...
  • hemeinvyiqiluoben
  • hemeinvyiqiluoben
  • 2014年12月04日 14:06
  • 8343

Caffe学习笔记(四)——Windows 下caffe配置相关问题说明

本文主要介绍:Win10 64位系统下,再次配置caffe,遇到了一些新的问题,现对这些问题及其解决方法进行总结。 详细的安装配置过程见以前博客:Caffe学习笔记(一)——Windows ...
  • hong__fang
  • hong__fang
  • 2016年09月01日 15:49
  • 9081

c# Windows窗体与事件驱动

创建Windows应用程序基本步骤 打开Visual Studio软件 新建项目 项目类型:Visual C#项目 模板:Windows 应用程序 熟悉开发环境窗体的常用属性窗体的属性非常多, 以下...
  • qq_36482772
  • qq_36482772
  • 2017年05月23日 04:16
  • 341

引入事件驱动机制的程序框架

  • 2014年04月05日 23:32
  • 250KB
  • 下载

事件驱动51程序通用框架代码

  • 2013年08月14日 16:49
  • 173KB
  • 下载

Java事件驱动程序设计相关代码

  • 2010年07月13日 11:18
  • 26KB
  • 下载

仿redis事件驱动程序

  • 2015年06月11日 19:20
  • 10KB
  • 下载

基于事件驱动单片机程序设计

  • 2014年07月03日 13:40
  • 101KB
  • 下载

Redis源代码分析之七:事件驱动库分析——Ae

aeEventLoop是一个记录记录程序事件状态的结构:/* State of an event based program */ typedef struct aeEventLoop { i...
  • Aegeaner
  • Aegeaner
  • 2012年02月27日 15:12
  • 4669
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Effective BCB Form Program(1) ——窗体事件驱动链引发程序错误分析
举报原因:
原因补充:

(最多只允许输入30个字)