|
8.4.2 创建OLE自动化服务器 OLE自动化服务器是应用程序或动态链接库(DLL),它可向OLE 自动化控制器输出OLE对象。 MemoEditdpr 就是OLE自动化服务器, 在MemoAuto 单元中注册了MemoEdit.Appdication自动化类,所有OLE控制器均可对MemoEdit.Application进行引用。 在Windows环境下有两种OLE自动化服务器,进程内服务器和进程外服务器,Delphi可创建这两种服务器。 进程内服务器是输出OLE自动化对象的动态链接库。因为OLE自动化对象来自于DLL, 对象是控制器程序的同一窗体进程,进程内服务器适合于创建共享的程序模块,而这个模块可以被用不同语言编写的多个程序所共享。进程内服务器被调用时在同一地址中运行,这样就不需要控制器进行调度,以避免处理大量的消息句柄。进程外服务器是能输出OLE自动化对象的应用程序。 有些OLE自动化服务器只能创建和输出一个OLE对象,有些服务器则可以处理多个OLE对象,另外一些服务器不能输出OLE对象,只能在程序内部使用OLE对象。 服务器与其能输出的对象数目的关系称为实例(instancing)。 在创建OLE 自动化对象时必须定义实例, 这样, 在创建一个OLE 自动化对象时,Windows就能决定是否创建一个新的服务器实例。表8.5列出三种实例类型。 表8.6 实例的取值及含义 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ instancing类型 含义 ────────────────────────────────────── internal OLE对象是应用程序的内部对象,对象不需要注册,外部进程不能创 建此对象 Single 每个服务器实例只能输出一个OLE对象实例, 若控制器需要多个OLE 对象实例,WIndows为第一个OLE对象创建一个服务器实例 Multiple 一个服务器能创建和输出多个OLE对象实例, 进程内服务器大多是 Multiple类型 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 每个使用OLEAuto单元的工程文件自动地拥有一个叫Automation的对象,它是非可视对象。就象Application部件拥有Delphi应用程序的一些信息一样,Automation对象也拥有服务器的一些信息,其中最重要的是StartMode属性和OnLastRelease事件。 StartMode指示OLE自动化服务器打开方式打开的目的。表8.7列出StartMode四种取值。 表8.7 StartMode 的取值及含义 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 取值 含义 ─────────────────────────────── SmStandAlone 用户启动应用程序 SmAutomation Windows为创建OLE对象而启动程序 SmRegSever 应用程序仅为注册一个或多个OLE对象而启动 SmUnregSever 应用程序仅为注销一个或多个OLE对象而启动 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 当StartMode模式是SmAutomation,而用户不再需要服务器时发生OnLastRelease 事件。此时所有OLE控制器释放了由服务器创建的对象。缺省情况下,服务器关闭实例,但OnLastRelease事件可根据实际情况是否关闭。OnLastRelease事件可得到一个叫ShutDown的布尔型变量。把ShutDown设置成True,则在最后一个OLE对象释放时服务器不关闭。 无论创建何种自动化服务器,必须定义对控制器的界面,包括定义和注册OLE对象,OLE自动化对象的属性和方法。定义界面主要是为了控制器能够引用它们。 对已存在的自动化服务器界进行修改时,要确保向上兼容 ,不要删去已有的属性、方法,这样会导致已存在的自动化控制器发生错误,修改服务器只能增加属性和方法。 创建OLE自动化服务器第一步是创建服务器自身。即创建能输出OLE对象的应用程序或动态链接库。这主要取决于是创建进程内服务器还是进程外服务器。 创建进程内服务器,即动态链接库: 1.创建动态链接库; 2.在工程文件的uses条款中加入OLEAuto单元; 3.在DLL中输出四个标准入口,即加入以下代码。 exports DLLGetClassObject,DLLCanUnloadNow; DLLRegisterServer,DLLUnregisterServer; 以上代码必须准确拼写,包括大小写。与ObjectPascal的其它项目不同,这些代码 对大小写敏感。 创建进程外服务器: 1.创建一个Delphi应用程序; 2.在工程文件的begin之后加入以下代码; if Automation,Server Registration then Exit; 创建服务器之后,应该向服务器加入OLE自动化对象,这个过程大部分是自动完成的,但必须向Delphi的自动化对象专家提供必要的信息。 把OLE自动化对象加入服务器: 1.在Delphi集成开发环境中选择File| New 菜单项,并在对象集中选择Automation Object,Delphi打开自动化对象专家。 2.给自动化对象命名 这是服务器内部标识OLE对象的名字,必须是个有效的面象对象Pascal标识符,习惯上以T字母开头; 3.给OLE类命名 该名用以外部控制器创建对象。当服务器在Windows中注册OLE对象,就以这个名字在系统注册。控制器使用这个名字调用CreateOLEObject来创建对象。 4.描述要输出的对象。 5.定义对象的实例(instancing),进程内服务器常定义为Multiple,进程外服务器常定义为Single; 6.选择OK键完成该过程 自动化对象专家将产生以下代码: ● 从TAutoObject派生下来的自动化对象定义,但没有定义任何属性方法; ● 调用DelphiOLE自动化管理器的注册代码,管理器负责Windows中注册服务器和对象。 在注册代码中包括一个自动产生的ID号,这个ID号是全局唯一的,通常不要修改。每个ID号与一个OLE类名相对应,如果其中之一被改变,应用程序在使用时会发生错误。 在创建了服务器并把OLE自动化对象加入服务器之后,控制器程序就可以对服务器进行操纵。 8.4.3 自动化另一程序 每个服务器在系统注册中有一个叫ProgID的关键定,主要用以控制器辨识服务器。任何控制器可以用ProgID号来创建OLE对象实例。例程AutoForm是控制器程序,它在其主窗体创建了OLE对象实例。 procedure TMainForm.FormCreate(Sender : TObject); begin try MemoEdit := CreateOleObject('MemoEdit.Application'); except MessageDlg( 'An instance of the "MemoEdit Application"OLE Automation Class could not be created,Make sure that the MemoEdit application has been registered using a "MemoEdit|regserver"command line', mtError,[mbok],0) Halt; end; end; 控制器创建了OLE自动化对象实例后,可对其进行操纵。OLE自动对象包括属性和方法,虽然OLE自动化对象与面向对象Pascal中的对象不是同一概念,但Delphi允许使用与类似的语法对OLE对象的方法进行调用。 AutoForm的很多过程引用了OLE自动化对象的方法: procedure TMainForm,TileButtonClick(Sender : Tobject); begin MemoEdit,TileWindow; end; 其中TileWindows是OLE对象TMemoApp中定义的方法。 AutoForm还通过TMemoApp的NewMemo方法获得了对服务器内部OLE对象TMemoDoc 的引用。 procedure TMainForm,CreateButtonClick(Sender : TObject); var I : Integer; begin CloseMemo for I := 1 to 3 do Memos[2] := MemoEdit.NewMemo; end; 其中NewMemo在MemoAuto单元中定义如下: function IMemoApp.NewMemo : Variant; begin Result := MainForm,CreateMemo(' '),OleObject; end; 控制器在获得服务器的内部OLE对象后,可以引用其方法: procedure TMainForm.AddTextButtonClick(Sender,TObject); var I : Integer; begin for I := 1 to 3 do if not var IsEmpty(Memo[I]) then Memo[I],Insert{'This text was added through OLE Automation'#13#10); end; Insert是TMemoDoc中定义的方法,用以在子窗体中插入字符串。
|