Effective BCB Form Program
- Form event drive chain trigger program error analysis
The class library used in the BCB is VCL, and its programming framework is an event-driven, similar to VB. I found in the development process, if you don't analyze the BCB's event drive chain, the written program will have a lot of errors, and the robustness is very problematic, and it is very troublesome to debug.
I found a lot of errors in the program coming from a pointer operation of C . An object is created in the program, and then DELETE is later, if there is this object to point to this object, the code to access this object will be able to trigger an exception. This is a common sense problem in C . But this problem is complicated in the development environment of BCB's event-driven development environment. Since the event model is actually a package for the Windows message loop mechanism, one message in Windows may trigger a series of other messages, so the events are also mutually triggered, forming an event-driven chain.
In the development environment of the BCB, the form is the core component, and the event model of the form is also the most important analysis in the program.
I have designed several typical situations in BCB5, which draws the event drive chains in the BCB for the event model provided by the BCB. Since the WM_PAINT message repeatedly stimulated, I consciously shielded the response event on this message onpaint. I found that most errors occurred in the process of forming a form, the main reason is that the programmer chosen the incident and put the code wrong place. Therefore, I focus on analyzing the creation of the form in the project and the event drive chain during the destruction process.
First analysis of BCB's engineering documents (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;
}
Winmain is the entry point of the BCB engineering, initialize () a completion process initialization work, createform () a creation of the form (in this series of events), the Run () has entered the message loop, at this time The event is mainly due to user operation (of course, there are events that are also triggered by operating systems such as timers).
Catch () a sentence to ensure that the application does not cause crash of the operating system. But this is also a countless BCB and Delphi program that will trigger the root cause of the "XXX memory read and write error". It is to improve the robustness of the BCB program, I have carried out this experiment, which is more boring, and people who don't want to see records can go directly to the conclusion.
Experimental record:
First, the FORM event drive chain that is automatically created by BCB
Experiment 1. There is only one main form of Form1 in the project
When there is only one main form (Form1) in the form, the order of the program running event is as follows:
create
FORM1 constructor àoncreate () // When this form is created, the following enters the form of the form.
àonshow () àonactivate () àoncanresize () àonconstrainedresize () àonresize ()
The form is displayed, the following enters the message loop, waiting for the user to enter.
shut down
Close the main form FORM1:
OnCloseQuery () àonclose () // To this exit message loop àonhide () àondestory () à ~ form1 () destructor
Obviously, a form must be hidden, then destroy, and finally call the destructor
In addition: onshow () à ... àonResize () This event chain is always constant in all situations, and I will represent these unchanged event chains in all records.
Experiment 2: There are two forms in the project, Form1 is the main form, and Form2 is a common form.
There are two forms in the project, Form1 is the main form, and Form2 is a normal form, the event chain is as follows:
create
FORM1 constructor à oncreate () // When this form FORM1 is created, started to create form2
à Form2 constructor
/ / The following process of entering Form1
àonshow () à ... àonresize ()
Unless specified in the code, the FORM2 is only in the load state, which is not displayed, and the event code in FORM2 is not running.
shut down
When it is closed, the FORM2 is in hidden or displayed:
Form1's onCloseQuery () àonclose () // This exits the project message loop, below FORM2
àform2 destructor àform1 onhide () àform1 onDestory () à ~ form1 () destructor
It is worth noting that at this time, FORM2's onDestory () is not executed, correspondingly, when it is created, FORM2's oncreate () has not been executed!
Experiment 3: Two forms in the project, Form1 is the main form, FORM2 inherits from Form1
In BCB, a form can be easily inherited, which is a very good feature of BCB.
create
FORM1 constructor à oncreate () // When this form FORM1 is created, started to create form2
àform2's oncreate () àform1 constructor àform2 constructor // below the display process of FORM1, the same single window, àonShow () à ... àonResize ()
It is worth noting that the oncreate () function of Form2 actually runs with the constructor of Form2!
shut down
1. FORM2 is hidden,
Form1's onCloseQuery () àonclose () // This exits the project message loop, below FORM2
àform2 destructor àform1 destructor àform2 OnDestory () àform1 onhide () àform1's onDestory () àform1 destructor
Note: The destructor of Form1 is executed twice!
2. FORM2 is displayed
Form1's onCloseQuery () àonclose () // This exits the project message loop, below FORM2
àform2 onhide () àform2 destructor à form1 destructor à form2 onDestory () àform1 onhide () àform1 onDestory () àform1 destructor
Note: The destructor of Form1 is executed twice!
In both cases, it can be found that there are only one FORM2 hidden process.