通过使用其他应用程序(可以使用自动的应用程序)和 ActiveX 控件的优势,可以扩展 Visual FoxPro 的功能。在应用程序的表单或通用型字段中,可以包含从其他应用程序中得来的特殊的功能或数据,例如文本数据、声音数据、图片数据或视频数据。可以使用创建这些数据的原应用程序,以可视的方式查看或操作这些数据;或者用自动服务(Automation)以编程方式控制应用程序,不可视但自动地操作数据。
其他应用程序也可以通过自动服务开发 Visual FoxPro 的功能。您甚至还可以在 Visual FoxPro 中创建自动服务程序(Automation Server)(COM 组件),使您的应用程序或其他应用程序可以进行本地或远程访问。
本章内容要点:
具有自动功能的应用程序和 COM 组件可以是自动服务程序 、客户应用程序 (Client),或者两者。作为服务程序的组件可以向其他应用程序提供对象;作为客户应用程序的组件可以创建对象。
可以很容易地在 Visual FoxPro 应用程序中合并 Microsoft Excel 和 Word 等应用程序的功能和灵活性。因为 Visual FoxPro 也可以作为服务程序,所以也可以把它的功能集成到基于 Microsoft Office 或其他 COM 组件的解决方案组中。
可插入的 OLE 对象来自于支持 OLE 的应用程序,例如 Microsoft Excel 和 Word。这样的对象包括 Word 文档和 Excel 工作表。在表单上可以使用 OLE 容器控件链接或嵌入这些对象,并且可以在表的通用型字段中保存这些对象,使用 OLE 绑定型控件在表单上进行显示。
在 Visual FoxPro 应用程序中,可以有很多方法来使用 OLE 和 ActiveX 技术。在创建应用程序之前,请仔细考虑使用的方式。
可以将其他 Windows 应用程序的文件嵌入或链接到表或表单中。例如,可以将一个 Word 文档嵌入或链接到表的通用型字段中,也可以把 Excel 电子表格嵌入或链接到表单上。
嵌入和链接的不同在于数据的存储地点。嵌入将数据存储到表或表单中,而链接却不是这样。例如,把一个 Excel 电子表格嵌入到一个表单上时,表单将包含该电子表格的副本。然而对于链接,表单仅包含对一个电子表格的引用,而不是电子表格本身。
嵌入和链接数据
嵌入和链接的数据一开始包含的都是服务程序文件中的原始内容,如下图所示:
在一个表单中嵌入和链接的工作表
但当初始文件改变时,链接的数据将自动更新以反映这些变化,而嵌入的数据则不能更新:
表单中链接的数据被更新
然而,嵌入的数据并不是静止的。嵌入和链接的数据都可以通过交互方式和编程方式来显示、更改和操作。
在表单或报表中,可以创建绑定到表的通用型字段上的对象。这些对象称作绑定型 OLE 对象,可以用它们来显示通用型字段中 OLE 对象的内容。使用“表单控件”工具栏上的“ActiveX 绑定控件”可以创建绑定型 OLE 对象。另外,也可以使用“ActiveX 控件”创建非绑定型 OLE 对象,非绑定型 OLE 对象不与表的通用型字段相连接。
您可以通过交互方式或者编程方式将 OLE 对象添加到表和表单中。
为应用程序设计表时,应考虑表中是否需要 OLE 对象。假设您有一个产品表,并想在此表中包含一些 Word 文档,其中含有具有格式优美的产品说明以便发送给大量潜在的顾客。要包含这些 Word 文档,则必须在表中定义一个通用型字段。然后,通过将文档链接或嵌入到通用型字段使其添加到表中。
若要在表中添加 OLE 对象
- 或者 -
有关使用表设计器添加 OLE 对象的详细内容,请参阅《用户指南》中的第十章“与其他应用程序共享信息”。
可以使用 APPEND GENERAL 命令,通过编程方式将 OLE 对象添加到表中。使用该命令,可以从一个文件中导入 OLE 对象,并将其放到通用型字段中。如果该字段已包含对象,则新对象将替换旧对象。
注释 与 APPEND 和 APPEND BLANK 命令不同,APPEND GENERAL 命令并不向表中添加新记录。
可以使用 APPEND GENERAL 命令嵌入或链接 OLE 对象,如 Excel 和 Word 等应用程序创建的 OLE 对象。这些应用程序支持链接和嵌入。但是某些应用程序,如 Microsoft Graph,仅支持嵌入。
假设您要将 Microsoft Word 文件存储到一个 Visual FoxPro 表中,而且该表有一个名为 WordDoc
的通用型字段,那么可以使用下列代码将文档嵌入:
CREATE TABLE oletable (name c(24), worddoc g)
CD GETDIR()
nFiles = ADIR(aWordFiles, "*.doc")
IF nFiles > 0
FOR i = 1 to nFiles
APPEND BLANK
REPLACE Oletable.Name WITH aWordFiles(i,1)
APPEND GENERAL WordDoc FROM aWordFiles(i,1)
ENDFOR
ELSE
MESSAGEBOX("No Word files found.")
ENDIF
注释 前面的示例只查找以 .doc 结尾的文件,这是 Word 文件使用的标准扩展名。因为 Microsoft Word 和 OLE 能识别这种文件扩展名,所以使用 APPEND GENERAL 命令时,这些文件就自动与 Word 服务程序联系起来。
如果使用与服务程序要求不符的扩展名,则必须用 CLASS 子句声明服务程序的类。例如,如果将 Word 类添加到前面的示例中,代码变成:
APPEND GENERAL WordDoc FROM wordfiles(i,1) CLASS "Word.Document.6"
如果文件的扩展名是一个常用的扩展名,并且有很多服务程序支持此格式的文件(例如,.bmp),那么可以用 CLASS 子句指定将要使用的服务程序。相应地,如果要链接对象而不是嵌入对象,可使用 LINK 关键字。
APPEND GENERAL WordDoc FROM wordfiles(i,1) LINK CLASS "Word.Document.6"
另外,使用 APPEND GENERAL 命令的 DATA 关键字能够替换对象中的数据,正如下面的 Microsoft Graph 示例所示。
Microsoft Graph 是一个嵌入的应用程序。Microsoft Graph 图表中的值基于 Microsoft Graph 数据工作表中的值。
通用型字段中的 Microsoft Graph 对象
为了通过编程方式更改 Microsoft Graph 图表中的数据,需要建立一个包含新数据的字符串,包括制表符、回车符和换行符,并将这些字符串通过 APPEND GENERAL 命令的 DATA 子句传递给 Microsoft Graph 对象。
下面的示例假设您有一个名为 stock
的表,包含 date
和 close
字段还有其他字段,前两字段分别代表日期和股票收盘价。Microsoft Graph 对象存储在 graph
表的通用型字段 msgraph
中。本示例用前 30
天的股票收盘价刷新图形。
代码 | 注释 |
|
定义回车符和制表符。 |
|
选择想用来更新图的数据,在这里是日期和最后 30 天的股票收盘价。 |
|
从临时表的数据中生成一个字符串 (lcData ) 来刷新图形。
“Closing Price”,作为列标头,是图例中默认显示的文字。 |
|
将新值通过 APPEND GENERAL 命令的 DATA 子句传送到 graph。 |
|
关闭临时表。 |
注释 也可以在报表中显示通用型字段里的 OLE 对象。有关在报表中显示 OLE 对象的详细内容,请参阅《用户指南》第七章“设计报表和标签”中的“添加通用型字段”。
使用表单设计器,可以使用“ActiveX 控件”向表单中添加可插入的 OLE 对象。另外,可以使用ActiveX 绑定控件,显示通用型字段中的 OLE 对象。
若要在表单中添加 OLE 控件
“插入对象”对话框
也可以自定义“表单控件”工具栏,这样就可以直接添加特定的 OLE 对象。
若要从“表单控件”工具栏中添加 OLE 对象
“选项”对话框的“控件”选项卡
若要显示通用型字段中的 OLE 对象
如果表名为 Inventory,通用型字段名为 Current,那么将 ControlSource 属性设置成 Inventory.Current。
也可以通过编程方式显示通用型字段中的 OLE 对象。
代码 | 注释 |
|
创建表单。 |
|
添加控件。 |
|
将数据与控件绑定。 |
|
使控件和表单可见。 |
如果向表单或通用型字段中添加一个 OLE 对象,就可以在运行时刻或设计时刻编辑数据并显示对象的特性。
注释 不能在设计时编辑一个 OLE 绑定型控件中 OLE 对象的数据。
有些 OLE 对象支持现场编辑,这样就可以在应用程序所用的窗口中编辑对象。例如,如果双击通用型字段中的 Microsoft Excel 工作表对象,而不是在另一个窗口中启动 Microsoft Excel 的副本,则当前菜单标题发生更改以反映出 Microsoft Excel 的菜单结构,并显示 Excel 的默认工具栏。您或者您的应用程序用户不必离开应用程序就可以编辑 Excel 对象。
注释 您只能现场编辑嵌入的对象,而不能编辑链接的对象。
您也可以在另一个窗口打开自动服务程序,在那里编辑数据或显示特性,然后当返回到应用程序时新值将反映到应用程序中。
若要在通用型字段窗口中编辑一个 OLE 对象
例如,如果对象是 Word 文档,请选择“文档对象”菜单项;如果对象是一个 Microsoft Graph 图表,请选择“图表对象”。
- 或者 -
若要在通用型字段窗口中打开一个 OLE 对象的应用程序
当向表单中添加一个 OLE 对象时,无论是用 ActiveX 控件还是 ActiveX 绑定控件,您都可以拥有更多的控制能力,而不仅是打开和编辑对象。
通过设置 ActiveX 绑定控件或 ActiveX 控件的 AutoActivate 属性,可以决定当 OLE 对象获得焦点或当用户双击 OLE 对象时是否打开或编辑该对象。AutoVerbMenu 属性确定了 ActiveX 控件的快捷菜单是否允许用户打开或编辑 OLE 对象。
为了便于只能通过 DoVerb 方法程序以编程方式来打开或编辑 OLE 对象,需要将 AutoActivate 属性设置为“0 - 人工”,并且将 AutoVerbMenu 属性设置为“假”(.F.)。
当用户现场编辑一个 OLE 对象时,菜单栏显示该 OLE 对象的菜单,而不是应用程序的菜单。如果创建了一个菜单标题,并希望即使在用户编辑 OLE 对象时仍然显示它,请在“菜单设计器”的“提示选项”对话框中选择“位置”。有关详细内容,请参阅第十一章“设计菜单与工具栏”或者帮助主题 DEFINE PAD 中的 NEGOTIATE 子句。
ActiveX 控件是封装了功能、属性、事件和方法程序的对象。ActiveX 控件提供了范围广泛的功能,这些功能可以容易地进行开发。与 Visual FoxPro 一起发布的 ActiveX 控件有:
ActiveX 控件是灵活多变的,因为可以通过把它们作为子类来创建其他控件,可以通过使用与 ActiveX 控件关联的事件、方法程序和属性来控制它们。不能使用 Visual FoxPro 创建 ActiveX 控件,但可以使用 Microsoft Visual C++® 4.0 和 Microsoft Visual Basic® Control Creation Edition version 5.0 提供的 Microsoft OLE Custom Control Developer’s Kit 来创建它们。
有关访问 ActiveX 控件的详细内容,请参阅第二十七章“使用外部库扩展 Visual FoxPro 的功能”。有关创建适用于 Visual FoxPro 的特定 ActiveX 控件的详细内容,请参阅第二十八章“访问 Visual FoxPro API”。
Visual FoxPro 中的 ActiveX 控件必须包含在一个 OLE 容器控件中(基类是 OLEControl)。当向表单添加一个 OLE 容器控件时,可以选择想添加到表单中的 ActiveX 控件。
若要向表单中添加 ActiveX 控件
“插入对象”对话框
如果 ActiveX 控件支持简单的数据绑定,Visual FoxPro 会公开该控件的 ControlSource 属性。用户所做的只是将 ControlSource 属性设置为一个表字段,则在 ActiveX 控件中显示的值将反映此字段的值。对控件中值的更改将保存到字段中。
有关使用 ActiveX 控件的示例,请在 Visual Studio ...\Samples\Vfp98\Solution 目录下运行 Solution.app。
注释 为了确保所有的 ActiveX 控件事件都能被处理,请将 Visual FoxPro 应用程序对象的 AutoYield 属性设置为“假”(.F.)。
表单或程序中的 OLE 对象,或者 OLE 容器控件中的 ActiveX 控件,都可以通过代码来管理,管理的方式与管理 Visual FoxPro 内部对象的方式相同。
在代码中,可以通过对象的属性来管理对象。引用属性的方式取决于该对象是单独的,还是容器的一部分,例如 ActiveX 控件或 ActiveX 绑定控件。
注释 ActiveX 控件总是 OLE 容器控件的一部分。
容器中的对象具有两部分:对象本身和包含对象的容器。对象和容器都具有属性,并且有时它们具有相同的属性名。为了确保引用的是对象的属性,请在对象名后面紧跟该对象的属性。例如,下面的代码引用的是对象的 Left 属性。
frm1.olecontrol1.Object.Left = 25 &&
对象的Left
属性
如果略去对象名称,则引用的将是容器的 Left 属性。
frm1.olecontrol1.Left= 25 &&
容器的Left
属性
例如,假设有一个应用程序,当用户单击一个组合的命令按钮时发送邮件。如果在表单中已加入了一个 Microsoft MAPI 消息控件 olecontrol1
,与命令按钮相关的 Click 事件的代码可以如下:
THISFORM.olecontrol1.Object.Compose
THISFORM.olecontrol1.Object.Send(.T.)
除了使用 Object 属性来引用容器包含对象的属性,也可以使用容器控件的其他属性。例如,可以引用只读的 OLEClass 属性来辨别容器中对象的类型;引用 Sizable 属性来防止用户更改对象的大小。有关容器控件属性的详细内容,请参阅“ActiveX 控件”。
在“表单设计器”和“类设计器”中,ActiveX 控件的属性显示在“属性”窗口中,但是大多数 ActiveX 控件也具有自己的界面用于设置公共属性。通过从 ActiveX 控件的快捷菜单中选择特定对象的属性,则可以看到这一属性界面。例如,要想打开一个 rich text 控件的属性对话框,在快捷菜单中选择“RichTextCtrl Properties”对话框。
打开 RichText 控件属性对话框
除了设置和检索对象的属性,还可以使用对象支持的方法程序来管理对象。例如,可以使用 Microsoft Excel 集合对象的 Add 方法程序新建一个 Microsoft Excel 工作簿。
下面的自动服务示例使用 Add 方法程序来创建一个 Excel 工作簿,Save 方法程序用来保存工作簿,Quit 方法程序用来结束 Excel:
代码 | 注释 |
|
启动 Excel。 |
|
显示 Excel。 |
|
创建一个工作簿。 |
|
设置单元格的值。 |
|
保存工作簿。 |
|
退出 Excel。 |
如果使用 OLE 容器控件或 OLE 绑定型控件创建了一个对象,可以使用该控件的 DoVerb 方法程序对该对象执行一个谓词。例如,使用 DoVerb(0) 执行默认谓词,使用 DoVerb(- 1) 激活对象以进行可视编辑,使用 DoVerb(- 2) 在独立的窗口中打开对象。
注释 请参阅应用程序的文档以确定支持何种自动服务命令。例如,Microsoft Excel 的加载项组件对在自动服务则不可用。
向一个 OLE 对象发出请求时,则自动服务程序处理它。无法过多地控制服务程序的进程,但是可以设置 OLERequestPendingTimeout 和 OLEServerBusyTimeout 属性来指定等待进程直到结束的时间。设置 OLEServerBusyRaiseError 属性,您可以决定当这个时间用完后将发生的进程。
一种对象类型可以代表单个的对象或者相关对象的集合。例如,一个 Microsoft Excel Workbook 对象代表单个的工作簿,然而 Workbooks 对象代表所有当前加载的工作簿。由于 Workbooks 对象代表了一个对象集合,所以就称它为一个集合对象。
在代码中,集合是一个无序的列表,无论从集合中添加或移去对象时,其中对象的位置都会改变。可以使用集合的 Count 属性,通过在集合中循环遍历来访问该集合中的对象。Count 属性返回集合中各项的编号。也可以使用 Item 方法程序返回集合中的一项。
例如,使用下列代码可以显示 Microsoft Excel 工作簿中工作表的名称:
oleApp = CREATEOBJECT("Excel.Application")
oleApp.Workbooks.Add
FOR EACH x IN oleApp.Workbooks
? x.Name
ENDFOR
也可以访问集合中的子集合。例如,使用下列代码可以访问一定范围的单元格集合:
oleApp = CREATEOBJECT("Excel.sheet")
oleApp.Workbooks.Add
oleApp.Range(oleApp.Cells(1,1),oleApp.Cells(10,10)).Value=100
oleApp.Visible=.T.
可以向方法程序传递数组,也可以传递回数组。但是,您必须在数组名的前面加 @ 符号作为前缀,通过引用传递数组。
例如,若要向 Microsoft Excel 传递一个 Visual FoxPro 数组,请考虑下列代码。该段代码在 Visual FoxPro 中创建一个数组,并为数组赋了值,启动 Microsoft Excel,创建一个工作表,设置工作表中第一个单元格的值,然后将该值复制到数组包含的其他工作表中:
DIMENSION aV(3)
aV(1) = "Sheet1"
aV(2) = "Sheet2"
aV(3) = "Sheet3"
oleApp=CREATEOBJECT("Excel.Application")
oleApp.Workbooks.Add
oleI=oleApp.Workbooks.Item(1)
oleI.Sheets.Item(1).Cells(1,1).Value = 83
oleI.Sheets(@aV).;
FillAcrossSheets(oleI.Worksheets("Sheet1").Cells(1,1))
oleApp.Visible = .T.
反过来,下面的代码向 Visual FoxPro 返回一个数组,然后显示数组中的内容:
oleApp = CREATEOBJECT("Excel.Application")
aOleArray = oleApp.GetCustomListContents(3)
FOR nIndex = 1 to ALEN(aOleArray)
? aOleArray(nIndex)
ENDFOR
注释 使用 Visual FoxPro,不能向 OLE 对象传递超过二维的数组。有关在 Visual FoxPro 中操作数组的详细内容,请参阅第三章“面向对象程序设计”和“语言概述”。
当自动服务程序不可见或者在引用对象的作用域中没有变量,则自动释放自动服务程序。可以使用 RELEASE 命令释放与对象相关的变量。如果服务程序是可见的,请使用 Quit 方法程序释放对象。
通过派生 Visual FoxPro 提供的基类或 OLE 控件,您可以创建自定义的 OLE 对象。例如,下面的代码派生了 Visual FoxPro 提供的 Outline 控件子类:
派生 Outline 控件子类
代码 | 注释 |
|
声明变量并初始化。 |
|
创建表单,将自定义的 Outline 控件添加到表单中,然后为控件列出的的各项创建一个数组。 |
|
提示输入一个数据库名,此数据库中包含需要控件列出的信息。 |
|
从数据库中收集信息,然后将其添加到控件中。 |
|
使控件可见,然后显示表单。 |
|
定义 OLE容器控件的一个子类,并通过设置该容器的 OleClass 属性来添加一个 Outline 控件,并定义其他的可自定义设置 |
如果想要发布 OLE 应用程序,那么还有一些其他因素需要考虑。有关详细内容,请参阅第二十五章“生成可发布的应用程序”。
因为 Visual FoxPro 可以作为一个服务程序(具有二级兼容性),也可以作为一个客户应用程序,所以支持自动服务的应用程序可以创建 Visual FoxPro 的实例,运行 Visual FoxPro 命令,访问 Visual FoxPro 的对象。
使用 Fpole.dll,甚至可以在不支持自动服务的应用程序中管理 Visual FoxPro。
通过使用 Visual FoxPro 的 Application 对象可以从其他应用程序中控制 Visual FoxPro。只要启动 Visual FoxPro,就直接通过 DDE 或自动服务自动创建了一个 Application 对象。
例如,下列位于 Visual Basic® 中或 Microsoft Excel 模块中的代码创建了一个对 Visual FoxPro Application 对象的引用:
Dim oFox as Object
Set oFox = CreateObject("VisualFoxPro.Application")
引用一个 Visual FoxPro 的 Application 对象后,就可以调用与该应用程序对象相关的方法程序,并且可以通过此 Application 对象的属性集合来访问其他对象。
Application 对象的方法程序
DataToClip | Help |
DoCmd | Quit |
Eval | RequestData |
下例在一个 Excel 模块中使用 Visual Basic for Applications 代码创建一个 Visual FoxPro Application 对象,然后打开 Visual FoxPro 表,将查询结果添加到活动的电子表格中:
Sub FoxTest()
Dim oFox as Object
Set oFox = CreateObject("VisualFoxPro.Application")
oFox.DoCmd "USE customer"
oFox.DoCmd "SELECT contact, phone FROM customer
WHERE country = " + Chr$(39) + USA+ Chr$(39) + " INTO CURSOR cust"
oFox.DataToClip "cust",,3
Range("A1:B1").Select
ActiveSheet.Paste
End Sub
只要启动 Visual FoxPro,就直接通过自动服务或者是 DDE 自动创建了一个 Application 对象。这个 Application 对象通过集合属性提供了对所有在 Visual FoxPro 工作期内创建的其他对象的访问。
Visual FoxPro Application 对象模型
Visual FoxPro Application 对象和 Visual FoxPro 中所有容器对象都具有与之相关的一个计数属性和一个集合属性。该集合属性是一个引用集合所包含对象的数组。计数属性是一个数值属性,它表明了所包含对象的数目。
下表列出了对象以及相应的集合属性和计数属性。
这些属性允许您通过编程方式使用循环语句来处理所有的或特定的对象,这些对象都包含在例如 Application 的容器对象中。例如,下面的代码将所有表单的 Visible 属性设置为“真”(.T.):
FOR EACH Form IN Application.Forms
Form.Visible = .T.
ENDFOR
使用 Visual FoxPro,可以创建自动服务程序(COM 组件),其中包含一些代码,用于执行对许多应用程序都通用的任务,或是用于实施复杂的商业规则。这些任务和规则对于公司中其他程序员和采用支持自动服务工具的用户而言,是可用的。
例如,您可以创建一个或多个类来运用企业级商业规则。使用该商业规则对象的客户应用程序,可以在方法程序的调用中传递输入的参数,随后自动服务程序可以做大量的工作,在返回结果之前从不同的数据源中检索数据并进行复杂的计算。
在 Visual Studio …\Samples\Vfp98\Servers 目录中安装了自动服务程序的示例。
在 Visual FoxPro 中创建一个自动服务程序,只需要在项目中包含定义为 OLEPUBLIC 的类即可。可以在项目中包含任意多个 OLEPUBLIC 类,可以在程序文件 (.prg) 或类库 (.vcx) 中定义它们。
例如,下面程序文件中的类定义创建一个自定义的 OLEPUBLIC:
DEFINE class person AS CUSTOM OLEPUBLIC
FirstName = SPACE(30)
LastName = SPACE(45)
PROCEDURE GetName
RETURN THIS.FirstName + " " + This.LastName
ENDPROC
ENDDEFINE
在“类设计器”中设计类时,在“类信息”对话框中选择“OLE 公共”,就可以指明该类为 OLEPUBLIC 类。
“类信息”对话框
在 Visual FoxPro 中,可以创建进程外或进程内的自动服务程序。进程外组件是一个可执行文件(.exe 文件),它在自己的进程中运行。客户应用程序和进程外服务程序之间的通信称为进程间通信。进程内组件是一个动态链接库 (dll),它运行时所位于的进程地址空间与客户应用程序调用它时所在的地址空间相同。
两者各有好处。进程内的服务程序更快一些,因为它没有进程间的通信负担。而另一方面,进程外的可以在远程进行调度,而进程内的则不能。另外,因为进程内服务程序和客户应用程序共享一个进程地址空间,.dll 中任何严重的错误都会中止客户应用程序,然而进程外的出错时,.exe 只中止服务程序。
当使用 OLEPUBLIC 类创建可执行文件时,.exe 文件不会丢失任何正常功能。这个可执行文件仍可以运行,提供一个用户界面,并且提供应用程序中的所有正常功能。您只是扩展了程序,但是,其它应用程序只能访问您指定的一些功能。
注释 如果多个用户访问自动服务程序,可能发生冲突。如果为应用程序功能提供了自动服务访问以及用户界面,请在界面上提供用于一致性检查的附加层次,以确保环境没有被更改。
若要编译自动服务程序
“连编选项”对话框
- 或者 -
连编了项目之后,可以在“项目信息”对话框中看到服务程序的类。在该对话框中还可以为每个类指定帮助文件和一个帮助主题 ID。这个帮助文件可以在大多数通用的浏览器中打开。
“项目信息”对话框
可以在“项目信息”对话框中选择类指定实例值。这些实例选项有:
注释 如果在“项目信息”对话框中的“服务程序”选项卡中进行了修改,为了使新的设置生效,需要重新连编 .dll 或 .exe。
当使用 OLEPUBLIC 类连编项目时,创建了三个文件。
类库文件是一个二进制文件,列出了所有在自动服务程序上发布的类,以及它们的属性、方法程序和事件。OLE 对象浏览器可以读到这些信息,并在界面上显示它们。
注册文件列出了您的服务程序中类的全局唯一标识符(global unique Ids) (GUID)。
注释 除了.vbr 文件不包含固定的路径以外,.vbr 注册文件与 .reg 注册文件相同。
具有 GUID 特性的 .vbr 注册文件,用于项目中的每个 OLEPUBLIC 类
当自动服务程序添加到 Windows 注册表中以后,其他应用程序就可以使用该服务程序。连编自动服务程序时,自动在连编机器上注册,也可以在其他机器上注册服务程序。
在使用 Visual FoxPro“安装向导”创建安装盘时,安装程序会在用户的机器上注册服务程序。也可以人工注册服务程序。
若要注册 .exe 组件
例如,若要注册 Myserver.exe,可运行下面的命令:
myserver /regserver
若要取消 .exe 组件的注册
例如,若不想注册 Myserver.exe,可运行下面的命令:
myserver /unregserver
若要注册 .dll 组件
例如,要想注册 Myserver.dll,可运行下面的命令:
REGSVR32 myserver.dll
若要取消一个 .dll 组件的注册
例如,若不想注册 Myserver.dll,可运行下面的命令:
REGSVR32 /u myserver.dll
注释 注册文件包含文件完整路径名,所以若移动了文件,需要重新注册它。
可以创建自动服务对象的应用程序都能创建基于自动服务程序的对象,并且将对象的属性设置为非隐藏类型或被保护类型,然后调用方法程序。例如,假设服务程序名为 foxole
,并且包含了一个名为 person
的类,它具有 GetName 方法程序,下面的代码可以在 Visual FoxPro 3.0 中运行:
oTest = CREATEOBJECT("foxole.person")
cName = oTest.GetName()
类似的代码可以在 Microsoft Excel 或 Visual Basic 中运行:
Set oTest = CreateObject("foxole.person")
cName$ = oTest.GetName()
与自动服务程序(ActiveX 组件)提供的对象相交互的唯一方式是通过公开类的方法程序和属性。当一个客户应用程序调用一个对象的方法程序时,若在自动服务程序中产生了一个错误,该方法程序或者返回一个错误值或者在客户应用程序中产生错误。
客户应用程序决定是否警告用户,或者从另一个途径继续执行。自动服务程序本身从来不与用户交互。这使得自动服务程序的位置对客户应用程序而言是透明的。自动服务程序可以在用户的本地计算机上运行,或者利用 Visual FoxPro 的远程自动服务(Remote Automation)特性在网络服务器上运行。
在标准的自动服务方案中,客户应用程序和服务程序在同一个计算机上运行,并且共享相同的资源,例如内存和处理器。
在同一个计算机上的自动服务
当为自动服务创建了本地服务程序后,也可以在远程调度它们。远程自动服务提供与本地自动服务相同的灵活性、可扩展性和全部功能,但是由于远程自动服务是通过一个网络来实现的,所以它允许:
可以使用“远程自动化连接管理器”为远程自动服务配置服务器和本地计算机,该管理器保存注册时的设置。在服务器上运行的“自动化管理器”管理自动服务,这样,处理本地对象的同一代码可以自动处理远程对象。
远程自动服务
启动远程自动服务的第一步是配置服务器,使客户可以通过“远程自动化连接管理器”来访问服务器。
若要配置远程自动服务的服务器
在“远程自动化连接管理器”中允许客户访问之后,运行服务器上的“自动化管理器” — Autmgr32.exe。Autmgr32.exe 安装在 Windows 95 下的 System 文件夹中或者安装在 Windows NT 下的 System32 文件夹中。这样将启动与其他计算机的远程自动服务连接。
服务器配置完之后,可以配置本地的客户机。
若要为远程自动服务配置本地的客户计算机
CLIREG32 MYSERVER.vbr
下表说明了“远程自动化连接管理器”中“客户访问”选项卡的“系统安全策略”区的选项。
名称 | 值1 | 说明 |
禁止所有远程创建 | 0 | 不允许创建任何对象。 |
允许通过关键字进行远程创建 | 2 | 只有当选中“允许远程激活”复选框时才可以创建对象。下面的子键设置可以改变在 Windows 注册表中对象的 CLSID:
|
允许通过 ACL 进行远程创建 | 3 | 只有当 Windows 注册表的 CLSID 的“访问控件列表”包含用户时,一个用户才可以创建对象。只适用于 Windows NT。 |
允许所有远程创建 | 1 | 允许创建任何对象。请不要在开发环境之外使用。 |
1.“值”列出了在 Windows 注册表中的“自动化管理器”的 RemoteActivationPolicy 特选设置。
对于在任何 Windows 操作系统中运行的远程自动服务程序,远程调用过程 (RPC) 提供了下列权限等级。
名称 | 值 | 说明 |
Default | 0 | 使用网络默认值。 |
None | 1 | 无权限。 |
Connect | 2 | 与授权服务器连接。 |
Call | 3 | 当服务器接到请求时,只在开始调用每个远程过程调用时授权。不应用基于连接的协议序列(前缀为 “ncacn”)。 |
Packet | 4 | 确认所有接到的数据来自于所期望的客户。 |
Packet Integrity | 5 | 确认在客户端和服务器之间传递的任何数据都没有被更改。 |
Packet Privacy | 6 | 确认前次的权限等级,并将每次远程过程调用的参数值加密。 |
应该仔细考虑 RPC 权限的必要性,因为随着 RPC 权限等级的提高,性能会下降。可以为自动服务程序中的每个类指定一个权限等级,这样较高的等级,例如加密,就不必应用于整个组件。
例如,作为自动远程服务程序的已实施数据服务可能具有一个 Logon 类,用来传递用户信息和密码信息,并且这个类可能需要 Packet Privacy 级的权限。而服务程序公开的其他类可能会使用一个低得多的权限等级。
遇到困难时可以采取以下建议:
问题 | 操作 |
OLE 错误代码 0x800706d9:在端点管理器中没有更多的端点可用。 | 确定自动服务管理器正在服务器计算机上运行,并且在“远程自动化连接管理器”的“网络地址”中正确地输入了服务器计算机的名称。 |
在“自动化管理器”的“OLE 类”列表中没有 Visual FoxPro 应用程序。 |
|