Delphi7中单元文件内各个部分的执行顺序
注:本文主要是讨论delphi程序启动时和退出时的执行顺序,期间有些知识来源于Delphi帮助,有些来自《Delphi7程序设计教程》(这本书只告诉我有initialization 和 finalization 这两个关键字,但是没讲明白)(唉,现在的书只讨论框框架架,不讨论细节,写出来的东西让你看能看懂,别人一问或者自己一想,就是什么都不懂!讲的不细致呀!唉,自己琢磨吧!!)。代码用两排‘*’标明。
好了,进入正题,首先说明initialization 和 finalization 在代码单元中的位置:
************************************************************
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage('1 FormCreate');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
ShowMessage('1 Destroy');
end;
initialization
ShowMessage('1 ini');{单元初始化代码}
finalization
ShowMessage('1 final');{单元退出时的代码}
end.
************************************************************
initialization —— 在单元中放在文件结尾前,包含用来初始化单元的代码,它在主程序运行前运行并且只运行一次。
finalization —— 在单元中放在 initialization 和 end. 之间,包含了单元退出时的代码。在程序退出时运行并且只运行一次。
OnClose —— 在点击关闭按钮或执行该事件时调用。
OnCreate —— 在窗体创建时调用。(我的感觉:该事件是在窗体创建之后,即执行构造函数后才执行的)
OnDestroy —— 在窗体销毁时调用,一般用来销毁程序员自己定义(自己定义、创建,而不是直接从控件板拖拉过来的控件)的对象、变量、指针等等。(与析构函数的关系我还没弄清)
下面是执行顺序(如果程序中没有 initialization、 OnCreate、 OnClose、 OnDestroy、 finalization 中的任何一项,则相应跳过即可):
程序启动 --> 执行 initialization 处的代码 --> 执行窗体的构造函数并创建相应窗体和单元中的对象(如拖拉的控件对象,全局变量等) --> 执行 OnCreate 事件 --> 程序运行 --> 关闭主窗体(此处指调用主窗体的Close或点击主窗体的关闭按钮) --> 执行 OnClose 事件 --> 执行 OnDestroy 事件 --> 执行 finalization 处的代码
以上是对于单个窗体而言,下面是对于多个窗体:
新建一工程,创建3个Form,分别是form1、form2、form3,默认情况下form1为主窗体。
<1 begin>
程序启动 --> 执行 initialization 处的代码(先 form1 然后 form2 最后 form3 ) --> 执行窗体的构造函数并创建相应窗体和单元中的对象(如拖拉的控件对象,全局变量等) --> 执行 OnCreate 事件(先 form1 然后 form2 最后 form3 ) --> 程序运行 --> 关闭主窗体(此处指调用主窗体的Close或点击主窗体的关闭按钮) --> 执行主窗体的 OnClose 事件 --> 执行 OnDestroy 事件(先 form3 然后 form2 最后
form1 ,注意哟,顺序倒过来了。) --> 执行 finalization 处的代码(先 form3 然后 form2 最后 form1 ,注意哟,顺序倒过来了。)
<1 end>
为什么 OnDestroy 和 OnCreate 的顺序相反?为什么 finalization和 initialization 的顺序相反?大家好好想想吧!
另外:如果我在form1中uses 一下Unit2(form2的代码单元)执行顺序如下:
<2 begin>
程序启动 --> 执行 initialization 处的代码(先 form2 然后 form1 最后 form3 ) --> 执行窗体的构造函数并创建相应窗体和单元中的对象(如拖拉的控件对象,全局变量等) --> 执行 OnCreate 事件(先 form1 然后 form2 最后 form3 ) --> 程序运行 --> 关闭主窗体(此处指调用主窗体的Close或点击主窗体的关闭按钮) --> 执行主窗体的 OnClose 事件 --> 执行 OnDestroy 事件(先 form3 然后 form1 最后
form2 ,注意注意,不一样了。) --> 执行 finalization 处的代码(先 form3 然后 form1 最后 form2 ,注意注意,不一样了。)
<2 end>
多个窗体(单元)一些细节性的东西:
1)initialization
initialization 的执行顺序取决于哪个窗体先被调用,对于<1>,由于3个窗体之间没有 uses 和被 uses 的关系,所以按照工程单元uses 中的顺序执行(在工程单元中,如下):
************************************************************
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2},
Unit3 in 'Unit3.pas' {Form3};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.CreateForm(TForm3, Form3);
Application.Run;
end.
************************************************************
如果改变
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2},
Unit3 in 'Unit3.pas' {Form3};
成为
uses
Forms,
Unit2 in 'Unit2.pas' {Form2},
Unit3 in 'Unit3.pas' {Form3},
Unit1 in 'Unit1.pas' {Form1};
那么就是(先form2后form3最后form1)
对于<2>,由于form1中uses了Unit2,那么在编译Unit1之前必须先编译Unit2。顺序自然是(先 form2 然后 form1 最后 form3)
所以 initialization 的执行顺序首先看彼此单元之间是否有uses和被uses关系(简单的说就是:调用关系), 然后再看工程文件的uses的顺序。(呵呵,不要被uses弄混了!)
2)OnCreate
OnCreate 的执行顺序由工程单元中的如下类似代码决定
************************************************************
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.CreateForm(TForm3, Form3);
************************************************************
改变之后则相应发生改变。
3)OnDestroy
与OnCreate的顺序相反。(相反时一种对应,创建的顺序与销毁的顺序是相反的,这样是为了避免发生错误,这样也体现了编程要求思维严谨。)
4)finalization
与 initialization 的顺序相反。
再说说OnClose,
当调用窗体的Close或点击关闭按钮时调用该事件。
主窗体Close后,程序就退出。
非主窗体Close,仅仅是Close本窗体。(别说你在OnClose中调用其他窗体的关闭,那些不再讨论范围)
直接用Application.Terminate强制退出程序时,不调用OnClose事件。但 OnDestroy 和 finalization 要执行。
说了这么多,不知道有没有说明白问题。希望大家能领悟(俺表达能力比较差,呵呵~~~)。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=575307
---------------------
本文来自 云中雁012345 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/peixiaobin_blog/article/details/19009627?utm_source=copy
Delphi7中单元文件内各个部分的执行顺序的更多相关文章
- js函数和变量的声明与执行顺序
一.函数执行顺序 1.正常顺序 function f(){ alert(2); } f(); //alert 2 所有浏览器都能测试通过. 2.倒序调用 f(); //alert 2 function ...
- js函数和变量的执行顺序【易错】
js函数和变量的声明与执行顺序 一.函数执行顺序 1.正常顺序 function f(){ alert(2); } f(); //alert 2 所有浏览器都能测试通过. 2.倒序调用 f(); // ...
- SQL语句group by 与order by 执行顺序引发的一场“内斗”
直入主题!看看下面这SQL会不会报错?如果报错应该是什么错误! --说明:黑色字体都是列SELECT application_id, index_num, num, amount FROM `cred ...
- 《Java编程思想》学习笔记(二)——类加载及执行顺序
<Java编程思想>学习笔记(二)--类加载及执行顺序 (这是很久之前写的,保存在印象笔记上,今天写在博客上.) 今天看Java编程思想,看到这样一道代码 //: OrderOfIniti ...
- SQL 语句与性能之执行顺序
select * , t3.Name from t1 left join t2 on t1.sysno = t2.Asysno left join t3 on t3.sysno = t2.Bsysno ...
- JMeter专题系列(三)元件的作用域与执行顺序
1.元件的作用域 JMeter中共有8类可被执行的元件(测试计划与线程组不属于元件),这些元件中,取样器是典型的不与其它元件发生交互作用的元件,逻辑控制器只对其子节点的取样器有效,而其它元件(conf ...
- jmeter(六)元件的作用域与执行顺序
jmeter是一个开源的性能测试工具,它可以通过鼠标拖拽来随意改变元件之间的顺序以及元件的父子关系,那么随着它们的顺序和所在的域不同,它们在执行的时候,也会有很多不同. jmeter的test pla ...
- Java中普通代码块,构造代码块,静态代码块执行顺序
//执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. 1 普通代码块 1 //普通代码块 ...
- Select查询执行顺序
链接:http://blog.jobbole.com/55086/ 很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言.面向对象的程序语 ...
随机推荐
- redis集群——RPLR简笔(Redis+PostgreSQL+Linux(centos7)+RabbitMQ)
使用的是centos7. 1.下载最新redis源码,解压(2016-05-12最新版本为3.2.0,3.0及以上才有官方集群) 2.进入源码根目录(此目录下的redis-stable目录),找到ut ...
- c++枚举变量初始值
#include <iostream> // std::cout, std::boolalpha, std::noboolalpha enum foo { c = -1, a = 1, b ...
- 【技术累积】【点】【java】【21】序列化二三事
基础概念 把对象等转为二进制进行传输的是序列化,反之为反序列化: 应用场景一般为读写文件,传输数据/接口调用: Externalizable和Serializable java的序列化方式有两种: S ...
- 解决Mysql Workbench的Error Code: 1175错误
错误: Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE ...
- JNI数组操作
在Java中数组分为两种: 1.基本类型数组 2.对象类型(Object[])的数组(数组中存放的是指向Java对象中的引用) 一个能通用于两种不同类型数组的函数: GetArrayLength(ja ...
- 谈一谈a:link、a:visited、a:hover、a:active的正确使用顺序
前端路上,未来还远,所以基础部分必须扎实,走好现在脚下的每一步才是现在最重要的. 下面进入正题吧. 1. <a>标签 我们先说一说<a>标签是干啥用的. <a> 标 ...
- NFS指定端口,NFS缓存(转载)
nfs服务端: #编辑/etc/nfsmount.conf,在末尾添加: #RQUOTAD_PORT=30001#LOCKD_TCPPORT=30002#LOCKD_UDPPORT=30002#MOU ...
- How To:防火墙规则去重
主要命令 iptables-save| awk ' !x[$0]++ | iptables-restore 演示: [root@testname ~]# iptables -vL Chain INPU ...
- 洛谷——P2341 [HAOI2006]受欢迎的牛//POJ2186:Popular Cows
P2341 [HAOI2006]受欢迎的牛/POJ2186:Popular Cows 题目背景 本题测试数据已修复. 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所 ...
- P4047 [JSOI2010]部落划分(最小生成树)
题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗.只是,这一切都成为谜团了——聪 ...