《DELPHI经典编程入门(8).pdf》由会员分享,可在线阅读,更多相关《DELPHI经典编程入门(8).pdf(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Delphi园地 http:/ 第八章 对象链接与嵌入(一)第八章 对象链接与嵌入(一)对象链接和嵌入(Object Linking and Embeding)是一组服务功能,它提供了一种用源于不同应用程序的信息创建复合文档的强有力方法。对象可以是几乎所有的信息类型,如文字、位图、矢量图形,甚至于声音注解和录像剪辑等。Windows附件组中的书写器是应用OLE的实例,使用单击“对象|插入”菜单项,书写器弹出插入对话框,对话框中列出了多个OLE服务器程序,如公式编辑工具,绘图工具,报表生成工具。用户双击鼠标左键,可激活一个OLE服务器。在OLE服务器中可编辑OLE对象,当用户返回到书写器中时,在
2、书写器文档中将出现OLE对象。Delphi支持OLE技术,Delphi1.0可以创建OLE应用程序,Delphi2.0可创建OLE自动化服务器和控制器程序。本章通过例程介绍对象链接与嵌入的基本概念,Delphi创建OLE对象的方法,OLE自动化的概念以及如何开发OLE自动化服务器和控制器。8.1 OLE简介 8.1.1 OLE1.0和OLE2.0 迄今为止,有两种版本的OLE:OLE1.0和OLE2.0。当用户在OLE1.0 服务器中激活OLE对象,服务器程序在前台打开自己的窗体,并获得焦点。OLE窗体失去焦点,存在于单独的窗体之中。OLE2.0服务器采用“本地”(in place)激活方式。
3、本地激活意味着服务器菜单与应用程序菜单要进行融合,服务器的状态条更换应用程序状态条,服务器的工具条更换应用程序工具条。OLE对象在应用程序窗体中进行编辑,但所有过程均由服务器处理。创建OLE对象的服务器决定了OLE的激活方式。如果一个OLE1.0的对象在OLE2.0 编译的应用程序中打开,它将采用OLE1.0的方式。8.1.2 链接与嵌入 链接对象的数据保存在OLE服务器创建的文件中,嵌入对象的数据保存在OLE应用程序中。链接对象必须以文件形式保存,只有对OLE服务器已经创建好的OLE对象,才能进行OLE链接,链接的OLE对象文件可被OLE应用程序或其它程序进行修改,OLE 服务器和其它OLE
4、应用程序也可以访问和修改OLE对象。对象数据保存在某一处,但可以被多个应用程序访问。Delphi应用程序可以得到OLE对象文件中的最新数据。当OLE 对象数据被应用程序修改时,这些变化将在所有包含该对象的其它应用程序中体现。嵌入对象保存在OLE应用程序中,其它应用程序不能访问该对象。只有在OLE应用程序中激活OLE对象才能对其进行编辑。嵌入的OLE对象不需要保存在文件中,所有数据都在应用程序中,这就确保了OLE数据不会被偶然地删除或修改。不足之处是应用程序的规模因为保存了OLE数据而增大了。如果用户想保存对嵌入对象的修改,可以把OLE数据存入文件中,本章第3 节将详细讨论这个问题。表8.1 使
5、用链接或嵌入的原则。何时使用链接 何时使用嵌入 想要对源对象进行修改及将 对源对象进行修改,并将这 这些修改反映到其他与源对 些修改反映在一个特定的应 页码,1/19第八章 对象链接与嵌入(一)象链接的应用程序或文本中 用程序或文本中 源对象可能被多个OLE应 源对象不可能被一个OLE应 用程序应用程序频繁修改 用程序频繁修改 源对象的文件不会被频繁移 源对象的文件可能被频繁移 动,且不会被删除 动,且不会被删除 对象很大,一般通过网络或 对象很小,或对象很大却无法 电子邮件进行分配 通过网络或电子邮件进行分配 8.1.3 设计状态OLE对象的创建 在Delphi中,可分别在设计状态或运行状态
6、创建OLE对象,表8.2说明了两种状态创建对象的差别。表8.2 设计、运行状态OLE对象的创建 设计状态OLE对象的创建 运行状态OLE对象的创建 对象保存在运行文件中,增加了所需 对象保存在一个文件中或只在运行时 编译的程序的规模 才有,减小了编译程序的规模 开发者需在设计时访问OLE服务器 开发者不需要在设计时访问OLE服务器 运行时OLE对象已经创建,减小了 运行时OLE对象已经创建,增加了运行 运行时间 时间 OLE对象在设计运行时间可行性编辑 OLE对象只能在运行时编辑 应用程序的OLE对象数目在设计时已 应用程序可以在运行时创建新的OLE对 经确立 象 在设计状态,OLE服务器不能
7、被本地激活,只能在自己的窗体内激活。但在运行状态,只要OLE服务器支持本地激活,就可以使用这种方式。8.1.4 OLE类、文件、项目 OLE类决定创建OLE对象的服务器。有些应用程序需要创建多种类型的OLE对象,例如应用程序同时链接或嵌入公式、图片等。OLE类也决定OLE对象所包含的数据类型,链接或嵌入对象均要定义OLE类。OLE文件是包含OLE对象数据的源文件。链接对象必须使用对象文件,因为链接对象在文件中保存。如果应用程序从已存在的源文件中创建嵌入对象,也要使用OLE文件。例如,如果链接到QuattiPro笔记本的OLE对象TUTOR.WBI存储在D:DFFICEQPW目录下,则OLE文件
8、就是D:DFFICEQPWTUTOR.WBI。值得注意的是OLE文件只能为链接对象所定义,而对于嵌入对象,只需定义OLE类。页码,2/19第八章 对象链接与嵌入(一)OLE项目是代表链接或嵌入数据的OLE文件中的一部分。当应用程序希望OLE对象包含比OLE文件小的数据块时,则必须使用OLE项目。例如,在QuattiPro笔记本中,OLE对象链接了GasCosts的B4 到B5 范围的网格,OLE项目是$GasCosts;$B$4.$B$5。8.2 设计状态OLE对象的创建 Dephi可以在设计状态和运行状态中创建OLE对象。本节介绍设计状态OLE对象的创建。8.2.1 TOLEContaine
9、r部件 要创建OLE对象,需在窗体中加入OLE包容器部件。应用程序部件包含链接或嵌入的对象。用该部件可显示在OLE服务器编辑的数据。部件的ObjClass,ObjDoc,ObjItem 属性分别定义OLE类、文件、项目。要定义OLE对象是否本地激活,使用InPlaceActive 属性。如果OLE对象可以本地激活,OLE服务器菜单将与OLE应用程序的菜单进行融合,GroupIndex属性的值将决定菜单融合情况。8.2.2 OLE对象创建的步骤:1.在窗体中增加OLE包容器部件;2.在Object inspector中单击ObjClass或ObjDoc属性的省略按钮,将出现插入对象对话框;3.如
10、果要插入的OLE 对象已存储在文件中,选择“Creat From File”,而后定义该对象的文件名和路径名。如果是链接对象,则选择链接检查框。如果是嵌入对象,选择“Creat new”,并在对象类型列表框中选择OLE对象;4.选择OK按钮;如果是创建新对象,OLE服务器将激活,则可对OLE对象进行编辑,完成编辑后关闭OLE服务器。典型的例子是单击服务器中的“File”或“File|Update”菜单。5.此时ObjClass属性中包含了相应的值,如果OLE对象从已存在的文件中创建或插入一 个链接对象,ObjDoc属性包含了OLE文件。在设计对象状态时也可以粘贴OLE对象,其步骤如下:1.激活
11、服务器应用程序,选择OLE包容器部件;2.在服务器中,将数据或对象拷贝到剪切板;3.进入Delphi集成开发环境,选择OLE包容器部件;4.在 Object inspector窗体中选择ObjItem属性的省略()按钮;5.在列表中选择OLE对象;6.选择“Paste创建一个嵌入对象或选择Pastelink创建链接对象;7.选择OK。OLE包容器部件在此时初始化。如果粘贴一个嵌入对象,ObjClass属性将包含适当的值。如果粘贴一链接对象,ObjClass,ObjDoc,ObjItem属性将全部定义。OLE 应用程序部件包含代表OLE对象的图片。如果OLE服务器程序支持OLE对象的拖放功能,则
12、在设计状态从服务器中拖动对象至应用程序,应用程序将创建链接对象,具体步骤:1.激活服务器,并Delphi集成开放环境中选择要链接的对象;2.按隹鼠标左键拖动OLE对象至设计状态的窗体;页码,3/19第八章 对象链接与嵌入(一)3.松开鼠键释放OLE对象。窗体将创建OLE应用程序并进行初始化。8.3 OLE应用程序的开发 Delphi可以在设计状态和运行状态创建OLE对象,上一节介绍的是在设计状态如何创建OLE对象,这一节将通过例程介绍如何在运行状态创建OLE对象、粘贴对象、拖动对象,以及OLE 对象的文件操作。我们开发的 OLE.dpr是一个OLE应用程序的实例 8.3.1 OLE应用程序界面
13、开发 OLE.dpr采用了多文档界面,父窗体有菜单,工具条,状态条,子窗体有一个OLE包容器部件,下面分别加以介绍。8.3.1.1 OLE应用程序的菜单 OLE应用程序的菜单与其它应用程序的主菜单大体一致,如果应用程序中有支持本地激活的OLE 2.0对象,则要进行菜单融合。查阅OLE 服务器的资料可知道服务器是否支持本地激活。OLE应用程序菜单的GroupIndex属性决定融合菜单的位置,即融合菜单是更换主菜单,还是插入至应用程序的主菜单中。OLE服务器,将融合三组菜单:Edit,View,Help,每组菜单分配了唯一的组索引值。在OLE应用程序中任何索引值为1,3,5的菜单组在菜单融合时被O
14、LE服务器中具有相应索引值的菜 单更换。在本例程中,编辑菜单项在菜单融合时被服务器的Edit替换。如图8.3。要想保存应用程序中的菜单,分配有异于1,3,5的索引值。表8.3 融合后的菜单 菜单 索引值 功能描述 来源(OLE激活时)文件 0 使用文件和退出程序 OLE应用程序 Edit 1 编辑OLE对象 OLE服务器 对象 2 操作未激活的OLE对象 OLE应用程序 View 3 修改OLE对象的观测方式 OLE服务器 窗体 4 操纵窗体 OLE应用程序 Help 5 访问服务器在线帮助 OLE服务器 8.3.1.2 OLE工具条和状态条 当OLE对象被本地激活时,OLE服务器将试图用自己
15、的工具条和状态条替换OLE应用程序的。如果应用程序想要本地激活,就应该在应用程序中编写相应的代码让服务器使用工具条和状态条。要做到这点,必须:设置工具条和状态条 在应用程序中加入状态条 通过修改面板部件的属性创建工具条和状态条。当OLE对象被本地激活时,面板或其他对齐控制将与OLE服务器程序进行协调。这意味 页码,4/19第八章 对象链接与嵌入(一)OLE服务器可以替换OLE应用程序窗体中任何对齐控制,但锁定的控制不能被替换。例如,如果面板的align属性是alTop,alleft,alBottom,alIngh时,控制未锁定,OLE服务器可以替换。要使应用程序的工具条、状态条不被替换,可将l
16、ocked属性设置成真值。当OLE 对象被激活,OLE 服务器在状态条中显示有关信息时,OLE 应用程序部件的OnStatusLineEvent事件发生,一个文本字符会将从OLE服务器传至该事件句柄。OnStatusLineEvent事件句柄的MSG参数接受文本字符。以下代码用以状态条接收OLE服务器的信息:procedure TOLEObjectForm.OleContainerStatusLineEvent(Sender:TObject;Msg:String);begin OLEFrameForm.StatusBarPanel.Caption:=Msg end;8.3.2 插入OLE对象
17、运行状态时进行对象链接与插入也要用到插入对话框,Delphi中没有插入对话框部件,但可调用InsertOLEObjectDlg 函数来显示对话框。8.3.2.1 InsertOLEObjectDlg函数声明如下:function InsertOleObjectDlg(Form:TForm;HelpContext:THelpContext;var PInitInfo:Pointer):Boolean;其中参数Form是拥有插入对话框的窗体,一般将拥有OLE包容器部件的窗体名字传给Form.参数Helplontext为插入对象对话框定义在线帮助,如果应用程序没有在线帮助,HelpContext的值
18、为零,对话框中将不出现帮助按钮。参数PInitInfo是一个无类型指针,该指针指向一个包含初始化OLE 部件信息的内部数据结构。InsertOLEObjectDlg修改这个指针以指向一个有效的数据结构,该结构包含了对话框列表中被选择的OLE 对象初始化信息。当该指针被使用后,应调用ReleaseOLEInitInfo过程释放初始化信息所占用的内存。当用户选择OK 按钮关闭插入对象对话框,InsertOLEObjectDlg 返回真值,并把 PInitInfo指向包含OLE对象的初始化信息的数据结构。8.3.2.2 初始化OLE包容器部件 为了使OLE包容器部件包含OLE对象,必须对部件进行初始
19、化。初始化主要是定义部件的OLE类。如果定义了OLE文件和OLE项目,初始化完成后,OLE 应用程序部件将包含OLE对象。调用InsertOLEObjetDlg函数可在其参数PInitInfo获得关于OLE对象初始化的信息时,把它传递给OLE包容器部件的PInitInfo属性,OLE包容部件的ObjClass,ObjDoc,ObjItem属性将被自动定义。初始化完成后,OLE对象被击活。OLE服务器将获得控制,用户可通过OLE服务器对OLE对象进行编辑。当程序冻结OLE对象,OLE包容器部件将包含一幅图像或位图代表OLE对象。定义OLE包容器部件的AutoActive属性可重新激活OLE对象,
20、缺省情况下,双击OLE包容器部件可击活OLE对象。例程中初始OLE对象的代码如下:procedure TOLEObjectForm.InitializeOLEObject(Info:Pointer);begin 页码,5/19第八章 对象链接与嵌入(一)OLEContainer.PInitInfo:=Info;ReleaseOLEInitInfo(Info)end;该过程先将初始化指针传给OLE包容器部件的PInitInfo属性,而后释放其内存空间。当用户单击例程中的“编辑|插入”菜单项,将弹出插入对象对话框,选择对象类型后,OLE对象被激活,该过程的代码如下:procedure TOLEOb
21、jectForm.InsertObject1Click(Sender:TObject);var Info:Pointer;begin if InsertOLEObjectDlg(OLEFrameForm,0,Info)then InitializeOLEObject(Info);end;8.3.3 冻结OLE对象 如果OLE对象是OLE 1.0服务器创建,对象将在OLE服务器中被击活,焦点和控制移到OLE服务器中。要冻结一个由OLE 1.0创建的对象选择File|Exit菜单项。如果OLE 2.0服务器支持本地激活,激活OLE对象后OLE服务器将进行菜单融合,并转换工具条和状态条。要冻结对象,
22、只需在应用程序窗体中异于OLE包容器部件的任何地方单击鼠 标键即可。另一种冻结对象的方法是把OLE包容器部件的Active属性设置成假值。在例程中,“对象|冻结”菜单项实现冻结功能。代码如下:procedure TOLEObjectForm.Deactivate1Click(Sender:TObject);begin OLEContainer.Active:=False end;8.3.4 粘贴OLE对象 一些OLE服务器允许用户把OLE对象复制到剪贴板,如果一个OLE对象复制到剪贴板上,OLE应用程序可通过初始化OLE包容器部件来粘贴OLE对象。8.3.4.1 粘贴对话框 把OLE对象粘贴到
23、OLE包容器部件,要使用粘贴对话框,Delphi 中没有粘贴对话框部件,但可用PasteSpecialDlg函数显示粘贴对话框。PasteSpecialDlg 函数声明如下:function PasteSpecialDlg(Form:TForm;Const First:arrang;HelpConcert:THelpCOntext;var Forrmat:Word;var Hardle:THanlle var PInitInfo:Point):Boolean;页码,6/19第八章 对象链接与嵌入(一)PasteSpecialDlg参数定义如下:参数Form是拥有粘贴对话框的窗体,应把包含OLE
24、包容器部件的窗体名字传递给Form。参数Format是注册对象格式的数组,每组格式是BOLEFormat类型的数组成员。例如应用程序可注册两种对象格式。为嵌入对象注册FEmbedClipFmt,为链接对象注册FlinkClipFmt。BOLEFormat 声明如下:BOLEFormat:Record fmtID:Word;fmtName:array0.31 of char;fmtResultName:array0.31 of char;fmtMediun:BOleMedium;fmIsLInkble:Bool;end;fmtID是对象的剪贴板格式ID号,fmtID 可以是标准的剪贴板格式:CF
25、_TEXT,CF_BIFMAP。使用OLE 对象时,需注册新的剪贴板格式来处理OLE 对象。Windows的API中 的RegisterClipbordFormat函数注册格式。fmtName表示是对象的名字,用以定义出现在粘贴对话框中列表框 内的对象名称。在例程中,把“S”匹配给fmtName,OLE服务器自动地把格式化的名字代替“S”参数。例如,如果OLE服务器是画笔,在程序运行时“Paintbrush Picture Object”将代替“S”。fmtResultName,定义出现在粘贴对话框中结果检查框内的名字。在例程中,把“S”传给了fmtResultName。OLE服务器自动地把格
26、式结果名称代替“S”参数。例如,如果OLE服务器是画笔,程序运行时“Paintbrush Picture”将代替“S”。fmtMedium是BOLEMedium类型,是Windows决定对象格式的数据类型。例如,OLE 联 接对象的格式是BOLE_MED_STREAM。OLE嵌入对象的格式是BOLE_MED_STORAGE。BOLEMedium函数可计算出需要的BOLEMedium类型。fmtIsLinkale决定对象格式是否可联连。联连对象的fmtIsLinkable为真值。嵌入对象的fmtIsLinkable为假值。参数HelpContext 为粘贴对话框定义在线帮助。如果应用程序没有在线
27、帮助,HelpContext的值为零,对话框中将不出现帮助按钮。参数Form用以定义剪粘板上的格式,是由PasteSpecialDlg函数进行修改。因为使用粘贴对话框时,应用程序并不知道剪贴板的格式。因而用Format来处理剪贴板的数据。在本章例程中。PasteSpecialDlg 函数把format 变量修改成FEmbedClipFmt 或FLinkClipFmt格式,这两种格式是在主窗体的OnCreate事件中定义的。如果剪贴板上的数据不是OLE对象,Format将被修改成其它类型的格式,如CF_TEXT等。参数Landle定义剪贴板上的数据句柄。由PasteSpecialDlg函数进行修
28、改。当剪贴板的数据类型不是OLE对象时,需用Handle参数访问剪贴板数据。Handle是句柄类型。参数PInitInfo是一个指向OLE对象初始化结构的指针。前面在讲述初始化OLE应用程序部件时也用到了这种指针。PasteSpecialDlg函数将修改PInitInfo指针以使其指向一个有效的数据结构。该结构包括了粘贴对话框中被选中的OLE对象的初始化信息。下面介绍粘贴对话框中的部件。将剪贴板上的数据插入OLE应用程序,以实现对象嵌入,须选择Paste;在OLE服务器资源文件与OLE应用程序之间建立联连,以实现对象联连,须选择:Paste Line;页码,7/19第八章 对象链接与嵌入(一)
29、要将闻连与嵌入的对象显示成图标,选择Display As Icon。若这个检查框被选中,改变图标(Chang Icon)按钮将显示通过这个按钮可改变OLE对象的缺省图标或标签。如果数据不是注册的格式,Paste,Paste link选择键将变灰。用户无法从剪贴板上粘贴数据。在本章例程中,剪贴板上的数据只能是FEmbedClipFmt(嵌入对象)和FlinkClipFmt(链接对象)。用户在列表框中选择数据类型。有时数据被解释成多种类型。例如在包含OLE服务器功能的字处理器中把文本复制到剪贴板中。应用程序可以以文本和OLE对象两种方式粘贴对象。列表框中出现的选择项由OLE服务器决定。用户在粘贴对
30、话框中选择OK按钮,PasteSpecialDlg返回真值,关于OLE 应用程序的初始化信息贮存在PInitInfo所指向的结构中。8.3.4.2 在剪贴板中使用OLE对象 要把OLE对象粘贴到OLE应用程序中,必须用Windows的 RegisterClipboardFormat函数为链连对象、嵌入对象注册两种新的剪贴板格式。这些格式将在BOLEFormat记录的fmtIdt域中被用到。本章例程中,程序在OnCreate事件中注册OLE对象的剪贴板格式,以下代码是主窗体的OnCreate事件:procedure TOLEFrameForm.FormCreate(Sender:TObject)
31、;begin FEmbedClipFmt:=RegisterClipboardFormat(Embedded Object);FLinkClipFmt:=RegisterClipboardFormat(Link Source);Fmts0.fmtId:=FEmbedClipFmt;Fmts0.fmtMedium:=BOLEMediumCalc(FEmbedClipFmt);Fmts0.fmtIsLinkable:=False;StrPCopy(Fmts0.fmtName,%s);StrPCopy(Fmts0.fmtResultName,%s);Fmts1.fmtId:=FLinkClipFmt
32、;Fmts1.fmtMedium:=BOLEMediumCalc(FLinkClipFmt);Fmts1.fmtIsLinkable:=True;StrPCopy(Fmts1.fmtName,%s);StrPCopy(Fmts1.fmtResultName,%s);RegisterFormAsOleDropTarget(Self,Fmts)end;程序传给RegistClipBroardFormat函数一个描述格式的参数,它返回一个Word类型的值。该值能唯一的辨识新注册的格式。FEmbdeClipFmt,FlinkClipFmt 是TOLEFormat类的私有数据成员。声明如下:TYPE T
33、OLEForaneForm=Class(TForm)页码,8/19第八章 对象链接与嵌入(一)private FEmbedClipFmt:Word;FLinkClipFmt:Word;function CreateChild:TOLEObjectForm;public Fmts:array0.1 of BOleFormat;end;在注册剪贴板格式后,还必须定义OLE 格式才能进行对象粘贴。每种格式定义在BOLEFormat记录中。程序中可能注册标准剪贴板格式并用这种格式进行粘贴。例如:注册文本作为粘贴格式,将BOLEFormat记录为fmtId域定义为CF_TEXT,fmt Medium 域
34、定义为BOLE_MED_HGLOBOL。BOLEMediumCalc 函数可以根据定义的剪贴板格式计算出fmtMedium值。在本章例程中,程序注册了两种格式,一种是链接OLE对象的格式,另一种是嵌入OLE对象的格式。BOLEFormat类型定义在BOLEDefs单元中,BOLEMediumCalc函数定义在ToCtrl单元。因此主窗中的interface部分应加入这两个单元。interface use,BOLEDefs,ToCtrl,在粘贴OLE对象前,应用程序必须知道在剪贴板中是否有OLE对象。PasteSpecialEnabled函数可判断粘贴对话框是否有效。如果剪贴板上有Fmts定义的
35、任何一种格式,PasteSpecialEnable将返回真值,粘贴对话框才能成功地调用。反之调用粘贴对话框将不发生任何事件。以下代码实现“编辑|粘贴”菜单项的功能:procedure TOLEObjectForm.PasteSpecial1Click(Sender:TObject);var ClipFmt:Word;DataHand:THandle;Info:Pointer;begin if PasteSpecialEnabled(Self,OLEFrameForm.Fmts)then if PasteSpecialDlg(Self,OLEFrameForm.Fmts,0,ClipFmt,Da
36、taHand,Info)then InitializeOLEObject(Info)end;只有在粘贴对话框有效时“编辑|粘贴”菜单才有效,以下代码实现此功能:procedure TOLEObjectForm.Edit1Click(Sender:TObject);begin 页码,9/19第八章 对象链接与嵌入(一)PasteSpecial1.Enabled:=PasteSpecialEnabled(Self,OLEFrameForm.Fmts)end;8.3.5 释放OLE对象 从OLE服务器拖动OLE对象并将其放在OLE应用程序是一种方便的对象链接与嵌入的方法。通过拖放操作,用户不需要使用
37、插入对话框或粘贴对话框来定义OLE对象。而只需用鼠标键从OLE服务器中“抓”住OLE对象,拖至OLE应用程序,松开鼠标键,从而实现OLE对象的插入。8.3.5.1 注册OLE释放目标窗体 为了接收一个释放的OLE对象,必须有一个窗体在Windows中注册成OLE释放目标,用RegisterFormASOLEDropTarget函数可实现此功能。RegisterFormASOLEDropTarger(Form:TFrom;Const Fmts:array of BOlefrom).其中Form是OLE对象的释放目标窗体,在本章例程中,将子窗体传递给Form参数。Fmts是对象格式的数组。它是BO
38、LEFormat 类型的数组。所有要释放的数据必须用Fmts数组中相应BOLEFormat元素注册。在本章例程中,注册的Fmts 数组与主窗体OnCreate事件 声明的数组相同,即:联接对象格式和嵌入对象格式。如果想接收更多类型的释放数据,就必须在Fmts数组中加入其它元素。例如应用程序要接收释放的文本,Fmts需加第三个元素,其fmtId 域为CF_TEXT,BOLEMedium域为BOLE_MED_HGLOBL.拖放过程中不需要用BOLEFormat的fmtName,fmtResultName域,如果程序只进行拖放操作而不进行对象粘贴,可以不初始化两个域。在主窗体的OnCreate事件中
39、可调用RegisterFormAsOLEDropTorget。procedure TOLEFrameForm,FormCreate(Sender:TObject);begin Register FormASOleDropTarget(Self,Fmts)end;目录 上一页 下一页 Delphi园地 http:/ 第八章 对象链接与嵌入(二)第八章 对象链接与嵌入(二)8.3.5.2 在应用程序中释放OLE对象 当一个对象释放到一个窗体,该窗体发生OnDragDrop 事件。该对象定义为TDragDropEvent方法中的Source参数,而TDragDropEvent 方法是用来处理OnDr
40、agDrop事件”。如果Source 是一个OLE 对象,那么它是TOLEDropNotify 对象的派生类型。TOLEDropNotify对象有一个与OLE包容器部件PInitInfo属性相对应的PIniInfo属性。如果一个OLE对象被释放。PInitInfo指向OLE对象的初始化信息结构。要实现释放功能。只需将TOLEDropNotify的PInitInfo属性赋给OLE包容器部件的PInitInfo属性。以下为处理OnDragDrop事件的代码:procedure TOLEFrameForm.FormDragDrop(Sender,Source:TObject;X,Y:Integer)
41、;var 页码,10/19第八章 对象链接与嵌入(一)NewChild:TOLEObjectForm;begin if Source is TOLEDropNotify then begin NewChild:=CreateChild;with Source as TOLEDropNotify do NewChild.OLEContainer.PInitInfo:=PInitInfo end end;注意不要用ReleaseOLEInitInfo释放分配给PInitInfo属性的内存。Delphi自动释放这块内存。8.3.6 文件中的OLE对象 在OLE应用程序中,要保存对OLE对象的修改,需
42、将对象数据保存在文件中。如果对象是链接的数据,Delphi将自动的保存在源文件中。当对象被修改时,文件中的数据自动修改。如果对象是嵌入的,数据贮存在应用程序程序的窗体。要保存对嵌入对象的修改,应用程序应把数据保存在特殊的OLE文件中。如果要对已存文件的对象进行编辑,应用程序必须从文件中装入OLE对象。OLE包容器部件的SaveToFile方法可保存对象:OleCntainer1.SaveToFile(C:SALEs.OLE);OLE包容器部件的loadFromFile方法可把文件中的对象装入OLE包容器部件。OleContainer1.loadFromFile(C:SALEs.OLE)本章例程
43、使用了保存对话框和打开对话框来实现运行状态的对象保存和对象装入。在OLEObjectForm窗体加入保存对话框部件和打开对话框部件。其主要属性如表8.4:表8.4 保存对话框的属性及取值:属性 值 Name SaveAsDialog DefaultExit ole FileName.OLE Filter OLE files(*.OLE)|*.OLE 表8.5 打开对话框的属性及取值 页码,11/19第八章 对象链接与嵌入(一)属性 取值 Name OpenDialog DefaultExit ole FileName.OLE Filter OLE files(*.OLE)|*.OLE 用户单击
44、“文件|保存”菜单项实现OLE对象的保存。代码如下:procedure TOLEObjectForm.SaveAs1Click(Sender:TObject);begin if SaveAsDialog.Execute then OLEContainer.SaveToFile(SaveAsDialog.Filename)end;用户单击“文件|打开”菜单项实现对象文件装入:procedure TOLEFrameForm.Open1Click(Sender:TObject);var NewChild:TOLEObjectForm;begin f OpenDialog.Execute then b
45、egin NewChild:=CreateChild;NewChild.OLEContainer.LoadFromFile(OpenDialog.FileName)end end;8.4 OLE自动化 OLE自动化是Windows应用程序操纵另一个程序的一种机制。OLE 2.0提供了一种方法来集成应用程序,这就是应用程序之间的命令操作。利用OLE 2.0,程序员可以定义一组命令,使它们进入到其它程序中。这些命令可带参数。看起来很象应用程序在调用函数或过程一样。采用上述办法,可以在人不参与的情况下,就能使得两个应用程序的相互作用。被自动化的程序称作自动化对象或自动化服务器,操作或自动化其他程序的
46、应用程序称为自动化控制器或自动化页码,12/19第八章 对象链接与嵌入(一)客户器。Delphi2.0完全支持OLE2.0的应用程序自动化,可以用Delphi 2.0编写自动化控制器和服务 器。在应用程序之间可编程的潜能是巨大的。用户可以创建宏或者其它命令,使得某个应用程序能透过其它应用程序进行工作。已经存在的应用程序的宏语言很容易被扩展,它可以包括一组别的应用程序能够执行的命令和函数调用。现在介绍两个应用程序,其中MemoEdit.dpr 是多文档界面的文本编辑器,作为OLE自动化服务器,AutoFrom.dpr是自动化控制器。运行AutoForm前,在Delphi集成开发环境中单击菜单(r
47、un|parameters),Delphi弹出运行参数对话框,如图8.5,输入参数后运行状态如图8.6。AutoForm窗体的多个按钮。可对MemoEdit进行操作;如按Creat按钮,MemoEdit产生三个子窗体,如图8.7,按AddText,子窗体将出现This text was added through OLE Automation的字符串“MemoEdit包括三个单元:Mainfrom MDI主窗体 EditFrom MDE子窗体和自动化类 MemoAuto 应用程序自动化对象 下面结合例程讲述OLE自动化的基本概念及开发。8.4.1 TAutoObject对象 TAutoObje
48、ct 是Delphi自动化服务器中所有对象的基类,任何自动化对象都是从TAutoObject类派生出来的。OLE对象的定义与其它类的定义类似。它的automated部分象普通类的public部分,OLE控制器可引用在这部分声明的属性和方法。编译器把automated部分创建成OLE自动化对象的入口。但automated部分的代码有很多限制:属性方法可以定义,但不能定义域;所有属性、参数、函数类型必须是以下类型之一:SmallInt,Integer,Single,Double,Currency,TDateTime,String,WordBool,Varint 属性声明只能包括访问定义符(read
49、 and Write),其它定义符如index,stored,default,odefault均不能使用;访问定义符必须列出相应的方法标识符,不能使用域标识符;支持数组类型;不允许属性重载;方法是可以是虚拟的,但不能是动态的,允许方法重载。在EditFrom单元中定义了TMemoDoc类:type TMemoDoc=Class(TAutoObject)private FEditForm:TEditForm;funtion CretFileName:String;页码,13/19第八章 对象链接与嵌入(一)funtion CretModiFied:WordBool;procedure SetFi
50、leName(Const Value:String);automated procedure Clear;procedure Ineart(Const Text:String);procedure Save;procedure Close;procedure FileName:String read GretFileName write SetFileName;procedure Modified:WordBool read GretModified end;TMemeDoc类是MemoEdit程序的内部自动化类,因此不需要注册。外部OLE自动化控制器对它不能直接引用。如果要使外部控制器对自动