----------------------------------------------------------------------------------------------------------------------------

说明:

Initialize is the first method called by the project source file. It calls the InitProc procedure pointer. By default, the call to Initialize for the application does nothing because the default InitProc pointer is nil (Delphi) or NULL (C++) .
Initialize 是项目源代码调用的第一个函数。它调用InitProc过程指针。默认情况下,Application调用Initialize什么也不做,因为默认InitProc指针是空的。
To use Initialize, the InitProc pointer must be predefined. This can be accomplished in one of two ways:
为了使用Initialize,InitProc指针必须预定义,它有2种实现方式:
In Delphi, you can include a unit that assigns a procedure to InitProc in its initialization section, such as the ComObj unit. You can make this assignment in the initialization section of any of your units.
在Delphi里,你可以包含一个Unit单元,在它的initialization代码段里,给InitProc赋予一个过程。你可以在任何一个单元的initialization代码段里赋值。
In both Delphi and C++, you can create a custom initialization procedure that assigns a value to the InitProc pointer, and add a call to this procedure to the project source prior to the call to Initialize. (In Delphi, you can add it to the initialization section of the unit in which it is declared. In C++, you can use the pragma startup directive in that unit.)
在Delphi和C++里,你可以创建一个定制化的initialization过程,把它赋一个值给InitProc指针,并在项目源代码里对Initialize调用之前增加一个对此过程的调用。在Delphi里,你可以增加它到initialization代码段,在C++里,你可以使用pragma来启动这个指令。
Warning: Only one instance of InitProc can be defined in an application. If more than one unit assigns a value to InitProc, only the last assignment will work. You can, however, call the previous value of InitProc from an initialization procedure, so that all initialization procedures are executed.
警告:只有InitProc的一个实例可以被定义在application里。如果有多个单元给InitProc赋值,只有最后一个赋值会起作用。然而,你可以在一个initialization过程中使用InitProc的上一个值,这样所有的initialization过程都会被执行。

http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Forms_TApplication_Initialize.html
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/System_InitProc.html

----------------------------------------------------------------------------------------------------------------------------

最初,它定义在System.pas里:

InitProc: Pointer; { Last installed initialization procedure }

Forms.pas里(调用过程):

procedure TApplication.Initialize;
begin
if InitProc <> nil then TProcedure(InitProc);
end;

OleAuto.pas里:

var
SaveInitProc: Pointer; procedure InitAutomation;
begin
if SaveInitProc <> nil then TProcedure(SaveInitProc); // 3.先调用系统提供的InitProc函数
Automation.Initialize; // 4.再调用自己的函数(任何函数),这样对系统什么都不影响
end; initialization
begin
OleInitialize(nil);
Automation := TAutomation.Create;
SaveInitProc := InitProc; // 1.先把原先的InitProc记录下来
InitProc := @InitAutomation; // 2.把自己单元的函数指针赋值给InitProc(但一定要是全局函数)
end;

ComObj.pas里:

procedure InitComObj;
begin
if SaveInitProc <> nil then TProcedure(SaveInitProc);
if (CoInitFlags <> -) and Assigned(ComObj.CoInitializeEx) then
begin
NeedToUninitialize := Succeeded(ComObj.CoInitializeEx(nil, CoInitFlags));
IsMultiThread := IsMultiThread or
((CoInitFlags and COINIT_APARTMENTTHREADED) <> ) or
(CoInitFlags = COINIT_MULTITHREADED); // this flag has value zero
end
else
NeedToUninitialize := Succeeded(CoInitialize(nil));
end; initialization
begin
LoadComExProcs;
VarDispProc := @VarDispInvoke;
DispCallByIDProc := @DispCallByID;
SafeCallErrorProc := @SafeCallError;
if not IsLibrary then
begin
SaveInitProc := InitProc; // 同上
InitProc := @InitComObj;
end;
end;

ComServ.pas里:

procedure InitComServer;
begin
if SaveInitProc <> nil then TProcedure(SaveInitProc);
ComServer.FStartSuspended := (CoInitFlags <> -) and
Assigned(ComObj.CoInitializeEx) and Assigned(ComObj.CoResumeClassObjects);
ComServer.Initialize;
if ComServer.FStartSuspended then
ComObj.CoResumeClassObjects;
end; initialization
begin
OleAutHandle := SafeLoadLibrary('OLEAUT32.DLL');
ComServer := TComServer.Create;
if not ModuleIsLib then
begin
SaveInitProc := InitProc; // 同上
InitProc := @InitComServer;
AddTerminateProc(@AutomationTerminateProc);
end;
end;

DBTables.pas里:

procedure InitDBTables;
begin
if SaveInitProc <> nil then TProcedure(SaveInitProc);
NeedToUninitialize := Succeeded(CoInitialize(nil));
end; initialization
if not IsLibrary then
begin
SaveInitProc := InitProc; // 同上
InitProc := @InitDBTables;
end;
Sessions := TSessionList.Create;
Session := TSession.Create(nil);
Session.SessionName := 'Default'; { Do not localize }
InitializeCriticalSection(CSNativeToAnsi);
InitializeCriticalSection(CSAnsiToNative);
finalization
DeleteCriticalSection(CSAnsiToNative);
DeleteCriticalSection(CSNativeToAnsi);
Sessions.Free;
Sessions := nil;
FreeAndNil(BDEInitProcs);
FreeTimer(True);
if NeedToUninitialize then CoUninitialize;
end.

虽然VCL内部怎么使用它,已经清清楚楚、明明白白,但是为什么要提供这样一种机制,我想不明白。因为进入项目主程序的Begin End代码段后,程序员还不是想调用什么函数就调用什么函数。至于单元,也有initialization代码段来调用各种函数。所以TApplication.Initialize到底为什么会存在、为什么需要存在,我觉得自己还是不明白。相当于我明白了它的今生,却不明白它的前世。

swish和不得闲的回答:
Application.Initialize 写在Begin End 里是因为它想保证在调用它之前,所以的initialization里的东西都已经初始化完了。而你放在initialization里的话,它会与你引用的顺序会有关系,造成初始化的顺序可能不是预期。

我总结,Application.Initialize 出现的原因有4个:
1. 用一句代码就调用某些功能,避免在主工程里写一大堆的代码,可以保持整体代码的整洁
2. Application.Initialize 代码的执行,必须是在所有的单元的initialization之后,程序员的代码之前,而且只需执行一次。
如果放在单元的initialization里,则造成执行顺序不可控
3. 放在Application.Initialize的代码,关键在于它是放在begin end里,可以让程序员自己控制,甚至屏蔽掉。
4. 方便C++进行初始化某些代码,因为C++没有initialization代码段(实证,BCB的主工程代码里的第一句也是Application->Initialize())。

------------------------------------------------------------------------------------------------------------------------

Initialize方法

对应对象:TApplication

声明:procedure Initialize;

功能:Initialize方法一般是应用程序调用的第一个方法。当用户建立了一个新的Delphi应用程序项目时,Initialize将自动地被添加到用户的项目资源上,如果用户的应用程序不是一个OLE自动化服务器,则用户可以删除初始化的这一行代码。对于OLE的自动化服务器,Initialize将使用系统寄存器来存储OLE自动化服务器的类。一个OLE自动化服务器是一个应用程序或一个DLL,它将OLE对象输送给OLE自动化客户。

例子: 
program Project1;

uses 
  Forms, 
  Unit1 in 'Unit1.pas'{Form1};

{$R *.RES}

begin 
  Application.Initialize; 
  Applocation.Title:='Delphi TApplication Demo Program'; 
  Application.CreateForm(TForm1,Form1); 
  Application.Run; 
end;

http://www.delphitop.com/html/jichu/1804.html

TApplication.Initialize的前世今生的更多相关文章

  1. Delphi主消息循环研究(Application.Run和Application.Initialize执行后的情况)

    Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; 第一步,貌似什么都不做,但如果提前定义I ...

  2. [反汇编练习] 160个CrackMe之032

    [反汇编练习] 160个CrackMe之032. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...

  3. 一行代码设置TForm颜色的前世今生(属性赋值引起函数调用,然后发消息实现改变显示效果),TForm的初始颜色在dfm中设置了clBtnFace色

    来自万一的帖子:http://www.cnblogs.com/del/archive/2008/04/27/1173658.html的确做到了一行代码设置TForm控件的颜色(一点感想:Delphi程 ...

  4. webRTC前世今生

    WebRTC 的前世今生 本文由 rwebrtc 翻译 WebRTC 技术是激烈的开放的 Web 战争中一大突破.-Brendan Eich, inventor of JavaScript 无插件实时 ...

  5. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  6. load和initialize方法

      一.load 方法什么时候调用: 在main方法还没执行的时候 就会 加载所有类,调用所有类的load方法. load方法是线程安全的,它使用了锁,我们应该避免线程阻塞在load方法. 在项目中使 ...

  7. [C#] 回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性

    回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性 序 目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都尚未进入正式阶段.C# 6.0 ...

  8. docker4dotnet #1 – 前世今生 & 世界你好

    作为一名.NET Developer,这几年看着docker的流行实在是有些眼馋.可惜的是,Docker是基于Linux环境的,眼瞧着那些 java, python, node.js, go 甚至连p ...

  9. Atitit 智能云网络摄像机的前世今生与历史 优点  密码默认888888

    Atitit 智能云网络摄像机的前世今生与历史 优点  密码默认888888 用户名admin  密码aaaaaa 网络摄像机是一种结合传统摄像机与网络技术所产生的新一代摄像机,它可以将影像通过网络传 ...

随机推荐

  1. 网页制作之JavaScript部分 1 - 语法(复制教材内容)

    一.简介 1.JavaScript它是个什么东西? 它是个脚本语言,需要有宿主文件,他的宿主文件是html文件. 2.它与Java有什么关系? 没有什么直接联系,java是Sun公司(已经没有了,被O ...

  2. Win7 和 MAC 系统通过VMware共享文件夹(简单又好用,几乎什么都不用设置)

    Win7是Server,Mac是Client,VMware上运行Mac系统 1.在VMware的Options菜单中选择Shared Folders选项 2.选择Always enabled选项 3. ...

  3. handler.postDelayed()和timerTask

    public static void scrollToListviewTop(final XListView listView) { listView.smoothScrollToPosition(0 ...

  4. Spring源码解析——如何阅读源码(转)

    最近没什么实质性的工作,正好有点时间,就想学学别人的代码.也看过一点源码,算是有了点阅读的经验,于是下定决心看下spring这种大型的项目的源码,学学它的设计思想. 手码不易,转载请注明:xingoo ...

  5. 用ATL写简单的ActiveX控件 .

    我正在做的项目需要用读卡器来读数据,由于系统是B/S架构的所以只能把读卡器的驱动封装成一个无界面的ActiveX控件,这样web页面中的js代码才能访问读卡器其实做起来也挺简单的,我用的环境是VS20 ...

  6. 科尔尼咨询公司 - MBA智库百科

    科尔尼咨询公司 - MBA智库百科 科尔尼公司简介 科尔尼管理咨询公司(A.T. Kearney)于1926年在芝加哥成立,经过80多年的发展,科尔尼咨询已发展为一家全球领先的高增值管理咨询公司,科尔 ...

  7. Android Socket 开发技术

    根据之前的经验,应用软件的网络通信无非就是Socket和HTTP,其中Socket又可以用TCP和UDP,HTTP的话就衍生出很多方式,基础的HTTP GET和POST请求,然后就是WebServic ...

  8. Fragment保持状态切换,fragment状态切换

    在使用Activity管理多个Fragment时,每次切换Fragment使用的是replace,结果导致出现xxx is not currently in the FragmentManager异常 ...

  9. ADO.NET 1创建连接、执行命令

    一无参构造函数的形式: 创建连接.创建命令.执行命令: string connstr = @"server=.;database=TestDataBase;uid=sa;pwd=130988 ...

  10. Java GUI使用exe4j打包exe文件

    exe4j下载地址:http://blog.csdn.net/cciii/article/details/17083531 1.  在MyEclipse将java项目打包成可执行jar文件.项目结构如 ...