----------------------------------------------------------------------------------------------------------------------------
说明:
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 <> -1) and Assigned(ComObj.CoInitializeEx) then begin NeedToUninitialize := Succeeded(ComObj.CoInitializeEx(nil, CoInitFlags)); IsMultiThread := IsMultiThread or ((CoInitFlags and COINIT_APARTMENTTHREADED) <> 0) 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 <> -1) 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到底为什么会存在、为什么需要存在,我觉得自己还是不明白。