使用Delphi编写COM组件

第一章 在Delphi中使用接口

1.1 定义接口:
目的:什么是接口,以及和抽象类的关联以及不同点。
抽象类(备注理解接口最简单的方法)
永远不能创建一个抽象类的实例;
本身不能实现功能,依靠派生类实现;
接口
被申明为interface类型。接口名从字母I开始。类类型名从T开始。
所有的接口从IUnknown继承;
不能创建接口实例;
不能在接口中指定范围指示。所有的方法都是公有型(public),不能在接口中申明包括范围指示;
不能申明变量;接口只能决定提供什么样的功能,对于如何完成功能没有限制;
接口中申明的所有函数和过程,概念上都是虚抽象函数和过程;因此申明时不能带Virtual;
接口是不变的;
1.2申明一个接口
目的:如何声明一个接口
常用的接口:CLSID、IID、和LIBID;
GUID(Globally Unique Identifier)全球唯一标示符: CoCreateGuid产生(API);
CLSID(Class Identifier): 代表COM对象的类别,代表COM对象的CoClass;
IID(Interface Identifier): 代表一个COM对象的接口;
例如:如何建立COM对象的方法;
var
iRoot: IUnkown;
begin
...
iRoot := CreateComObject(ProgIDToClassID('Project1.Interface1')); //取得实体样例
...
end;
应用程序在内存中建立了COM对象的实体样例;
注意: CreateComObject回传的是COM对象的实体样例的IUnknown接口;
APPID(Application Indentifier): 应用程序ID;
CATID(Category Identifier): COM组件实现的组件类型;
LIBID(Library Identifier): COM对象实现的Type Library代表的ID;
ProgID: 有意义的字符串代表特定的CLSID;
1.3 实现接口
目的:如何实现接口
实现IUnknown: QueryInterface、 _AddRef、 _Release
使用TInterfaceObject来自动实现Iunknown,否则的话自己要实现上面的方法。
创建、使用及销毁接口: create;指向接口的指针不访问任何信息;自动释放、强迫销毁一个接口将变量置为nil
注:delphi自动创建和销毁接口。
获取单个接口的指针:
直接分配:类与他们实现的接口类型兼容的
GetInterface(const IID: TGUID; out obj):判断对象是否支持一个接口
as操作符: 对象支持特定的接口(对象不支持接口就错的话,可以拦截错误);
as自动调用计数功能;

1.4 高级多级接口问题
目的:在一个类中实现多个接口
在一个类中实现多个接口
TXY = class(TInterfacedObject, IXX, IYY): 类TXY 实现了IXX和IYY接口的所有方法。
多个接口不是多重继承:TXY有且只有一个基类TInterfacedObject;
方法分辨字句:当接口方法在类中实现时,方法分辨子句可使用改变他的名称
TXY = class(TInterfacedObject, IXX, IYY)
procedure IXX.pxy = pxy1
procedure IYY.pxy = pxy2

接口授权:一个接口的实现授权给另一个类:一个类包含针对另一个类的指针。
内部类: 实现一个或多个接口的功能性;
外部类: 简单的将这些方法传递给内部类,而不是重新实现接口;

接口属性:可以定义只读、只写、或者读写属性;
但是所有访问都必须通过访问函数,因为接口不能定义存储。 
1.5 小结
目的:如何在delphi应用程序中内部使用接口,了解delphi语言要素的接口。
申明一个接口; 
在类中实现接口; 
实现IUnknown所需要的功能; 
自动对象析构的处理; 
在类中实现多个接口; 
将一个接口的实现授权给一个内部对象; 
定义并实现接口属性。

 

第二章 接口与COM
2.1 GUIDs 和 COM
目的:
CLSID: Class ID是GUID一个具体的类型的名称,注册表 HKEY_CLASSES_ROOT/CLSID
每个接口CLSID或GUID都代表一个COM接口的实现 
COM对象: TCOMObject继承(TInterfacedObject不提供实现COM对象的必要功能)
Hresult: 特殊类型的返回值,意味着函数调用成功还是失败。
OleCheck: 检查函数调用可能产生的错误;当调用返回HResult的COM函数时应使用该函数;
类厂(Class Factory):
COM对象不是由程序直接例示的;
COM使用类厂来创建对象;
类厂是一个对象,目的就是创建其他对象;
每一个COM都有一个相关的类厂,负责创建在服务器中实现的COM对象;
类厂把COM从实际构造一个对象的过程中分离出来,COM没有对象构造过程
类厂支持IClassFactory接口: IClassFactory只定义2个函数CreateInstance和LockServer
CreateInstance函数: 负责创建类厂涉及的COM对象的实例的函数;
LockServer: 保持服务器在内存中,一般不要调用他;
类厂中的双重类:
2.2 进程内的COM服务器(In-Process COM Server)
目的:理解进程内的COM服务器
共性:有一个InprocServer32的子键、所有进程内服务器都输出以下四个标准函数;
DllRegisterServer: 2种方式自动调用
IDE的Register ActiveX Server菜单
Windows的命令行应用程序RegSvr32.exe(或Boland应用程序TRegSvr)
DllUnregisterServer: 是DllRegisterServer的逆进程,移走放在注册表中的条目;
DllGetClassObject:
负责提供给COM一个类厂,该类厂用语创建一个COM对象;
每个COM服务器将实现它输出的每个COM对象的类厂;
DllCanUnloadNow: 返回S_True,CO在内存中移走COM服务器;如果返回S_False

线程支持(Threading Support): 只适用于进程内服务器;被保存在注册表中;线程模型如下
Single-Thread Apartment(STA): 实际上根本没有线程支持,所有对COM服务器的访问由Windows顺序执行,不必考虑同步存取的问题。
Mutli-Threaded Apartment(MTA): 允许同时有多个线程存取COM对象,必须控制不同线程同步存取的程序代码;
Both Apartment: 可以执行在MTS或STA中;
自由的:
注册服务器(registering the Server): 所有的COM服务器都需要Windows注册表来工作。 
定制构造函数(Custom constructors): delphi中COM对象的基类包括一系列的非虚构造函数。
只需重载Initialize方法;
不要试图重载一个COM对象的构造函数;
创建一个进程内COM对象
function CreateComObject(const ClassID: TGUID): IUnknown;
CoCreateInstance内部创建负责创建COM对象类厂的实例,然后使用类厂来创建对象,创建完后COM对象后,类厂被销毁;
虚方法表(Virtual Method Tables):
接口实现为独立的方法表,该表实现在内存中紧靠VMT的地方;
不同的接口占据不同的内存部分,不能简单的把一个接口值赋给另外一个接口;
通常使用as操作符从一个接口转换为另外一个接口;
2.3 进程外COM服务器(Out-Of-Process COM Server)
目的:理解进程外COM服务器
进程外服务器是在exe中实现; 
实例化(Instancing): 创建多少个客户需要的实例;可以支持三个实例化方法中的一个;
Single Instace(单实例):
只容许一个COM对象的实例
每个需要COM对象实例的应用程序将产生COM服务器的单独拷贝;
Multiple Instance(多实例):
指COM Server可以创建一个COM对象的多个拷贝;
客户请求COM对象的一个实例时,由当前运行的服务器创建COM对象的一个实例;
Internal Only(内部实例):用于不被客户应用程序使用的COM对象;

调度数据(Marshaling Data):
一个可执行的程序不能直接访问另一个可执行程序的地址空间;
Windows通过调度(Marshaling)进程在调用应用程序和进程外COM服务器之间移动数据;
自动化兼容 SmallInt、Integer、Single、Double、currency、TDateTime、WideString、Idispatch、Scode、WordBool、Olevariant、IUnknown、ShortInt、Byte;
记录和数组不能自动调度;
2.4 Variant 数组
目的:如何使用Variant 数组;
Variant:
一种可以拥有各种数据类型;
也可以告诉目前存储的数据是什么类型(通过使用VarType函数);
可以给相同的Variant分配不同的数据类型,只要Variant包含数字值就可以执行算法;

variant数组只不过是variant型的数组,不必包含同类型的 数据; 
variant数组的创建方法:
function VarArrayCreate(const Bounds: array of Integer; VarType: integer): variant;
Bounds: 告诉数组的上下界;
VarType: 决定了数组的中存储什么类型的数据。

例如:创建数组的数组, 可以模仿任何类型的数据结构类型:
VarArrayX := VarArrayCreate([1,10], varVariant);
数组的单个元素可以装载一个数组: VarArrayX[1] := VarArrayCreate([1,5], varVariant);
function VarArrayOf(const Values: array of Variant): Variant;
运行时用于创建一维数组;
可以创建全异的数值数组;
例如: MyArray := VarArrayOf(['李维', 30, '60', 60.369, 'China']);

使用Variant数组: 与使用标准Delphi数组类似;
VarArrayLowBound、VarArrayHighBound(与数组的low、high类似)计算边界;
VarArrayDimCount:计算数组的维数;
2.5 小结
目的:接口GUID及进程COM服务器的基本知识了解;

Guid是什么;以及为什么Guid对COM是如此重要;如何创建Guid以供自己使用; 
进程内COM服务器,创建及如何使用; 
Variant数组; 是什么、及如何使用; 
进程外COM服务器的介绍、调度及Windows可自动调度的类型; 
只有能理解虚方法表(VMT)的面向对象的语言才能访问只有虚方法表的COM服务器。

 

第三章 类型库
3.1 定义类型库
目的: 类型库是什么,和它的作用是什么。

使用类型库的好处:
编写自动化控制时早期连接(Early Binding);
许多编译器可以从一种类型库中自动生成针对特定编程语言的代码;
实用程序可以用来读取并显示有关包含类型库的COM服务器的信息;
在COM客户和服务器之间自动参数调度;

类型库对某些COM服务器是必须的,例如:自动化服务器和ActiveX控件; 
TTypedComObject: Delphi由该类及其派生类提供了对类型库的支持;
Delphi自动创建XXXX_TLB.pas文件;
COM由TTypedComObject派生,而不是TComObjectFactory.Create;
初始时,delphi调用了TTypedComObjectFactory.create、而不是TComObjectFactory.Create;
3.2 使用delphi来创建类型库
目的: 如何使用Delphi来创建类型库的基本知识;

可以使用IDL(Interface Definition LAnguage 接口定义语言)编码类型库; 
类型库编辑器:
工具条:可以添加接口、方法、以及属性到COM服务器中;
注:工具条上可以通过点击鼠标右键弹出的菜单中选择Text Labels命令打开工具条的标题;
Interface(接口): 自动为每一个新建的接口产生一个GUId;
Dispinterface(派遣接口): 与接口类似,但是使用不同的派遣机制调用服务器中的方法;
CoClass(): 类别的定义,被指定给实现接口的COM对象;
使用COM对象之前必须先使用一种方法从类别定义建立真正的类别对象(变量);
再从类别对象取去需要的接口;
最后再从取得的接口中调用需要执行的方法或需要存取的属性;
Enumeration(枚举): 与枚举类型类似;有整数ID来指明,而不是通过集合类型;
Constant(常量):只有在枚举下才有用;可以编辑Name、Value属性;
Alias(别名): 用于定义用户要包括一条记录类型(record)或联合类型(union)中的类型;
Record(记录类型): 记录结构;
Union(联合类型): 等同于Pascal Variant类型;
Module(模块): 模块是方法和常量的集合;
Method(方法): 输入参数(in)、输出参数(out)、可变参数(var);
Property(属性): 只读、只写、读写三种;
Refresh(更新): 使Delphi更新源文件;
Register(注册): 编译COM服务器并把服务器注册到Windows中;
Export(输出到IDL): 在MIDL或Corba格式中很有用;

friend
对象列表(Object List):显示服务器中定义的接口、方法等;
控件(Page control):显示对象列表中当前选中的接点的类型信息;

类型库也是一种资源; 
不必在客户应用程序中直接读取类型库;
3.3 小结
目的: 类型库的运用;

类型库是什么; 
如何创建一个类型库; 
如何编译一个类型库类给自己的服务器添加方法、属性及枚举类型; 
如何读取类型库的信息。

 

第四章 自动化

通过自动化操作类型库;接口和自动化;Variants和自动化;派遣接口;双重接口;自动化ADO;
4.1 定义自动化
目的: 自动化以及客户通过使用接口、Variants派遣接口和双重接口创建并使用自动化服务器;

自动化是一种从应用程序的内部自动控制另一个应用程序的方法。 
获取自动化服务器的COM对象的两种主要访问方法:
接口:早期连接(early binding)
早期连接是指对接口方法的所有调用在编译时检查参数是否正确;
Variants: 后期连接 (late binding)
后期连接指连接意味着方法调用直到运行时才被实现;
Variant不是对象指针;对象的调用方法是后期连接;
编写快速、简单的客户应用程序不用费力去输入一个类型库;

派遣接口(DispInterface)
在接口和Variant中间的某个地方就是派遣接口;与接口有很多类似;
只是方便客户而设定的;
并没有在服务器上实现派遣接口;是服务器上实现了接口;
假设服务器的COM对象也支持IDispatch接口,客户应用程序可以使用Variants或派遣接口;

双重接口(Dual Interface): 自动化服务器
简单定义为自动化服务器,支持早期连接(接口)和后期连接(Variants);
使用delphi创建的任何任何自动化服务器将自动支持双重接口;
4.2 进程内自动化服务器
目的: 创建并使用进程内自动化服务器;

CreateOleObject和GetActiveOleObject
CreateOleObject:总是创建特定服务器的新实例;
GetActiveOleObject: 用来获取正在内存中运行的服务器的引用;
例如:
Procedure StartOrLinkToWord;
var v: Variant;
begin
try
v := GetActiveOleObject('Word.Basic'); //判断是否Wod已启动;
except
v := CreateOleObject('Word.Basic'); //否则启动Word; 通常自动化服务器启动是隐藏的;
v.AppShow; //显示Word应用程序;
end;
V.FileNew; //创建一个新的文档;
v.Insert('Automation is easy!');
end;

访问自动化服务器的方法:
Interface 通过接口;
Variant 通过Variant: 通过可使用的类名;CreateOleObject
DispInterface 通过派遣接口;
4.3 进程外自动化服务器
目的: 自动化的基础;创建一个Automation服务器,如何使用接口、派遣接口、和Variants来控制此服务器;

在本身应作为独立服务器应用程序的情况下,使用进程外非常好; 
HResult:
自动服务器中的所有方法必须返回一个HResult,暗示是成功还是失败;
所有其他参数必须在out参数中返回;

safecall:
调用协议可使编码;
指示Delphi自动把所有方法包括在try...except模块中;
在客户端safecall导致客户检查是否有HResult类型的返回失败码;
4.4 COM事件和回调
目的: 两种方式的比较;

派遣接口(DispInterface):
与Interface的比较
DispInterface: 为事件提供了更好的支持;与VB兼容;实现事件是最兼容的方法;
Interface: 不与VB兼容;但速度比派遣接口稍快;

回调接口(CallBack Interface):除非有极重要的原因否则不要使用;
服务器做大量的工作,而刻户端不需要太多的工作;
接口中定义回调方法,而不是使用派遣接口把事件送回到客户端;
回调接口在服务器中定义,但在客户中实现;
如果知道服务器和客户提供的接口,回调接口更有效;
4.5 自动化ADO: Microsoft最新的数据库技术;
目的:如何使用Delphi来快速、轻松的使用基于COM的技术;

主要组件:Connection、RecordSet、Command;
Connection对象: 用于连接到一个本地或远处的数据库;
RecordSet对象: 提供了一个记录集的连接;
Command对象: 向数据库发出命令,不返回结果集;

连接数据库:Connection.Open();  
记录集打开:RecordSet.Open();  
执行命令:对数据库进行操作,并返回结果集,应使用Command对象(与Parameter一起工作); 
访问字段值:
访问Field对象的值: RecordSet.Fields.Item[FieldNo].Value;
访问字段名称:RecordSet.Fields.Item[FieldNo].Name;

数据库错误处理:Error对象,该对象提供任何错误的详细代码;
4.6 小结
目的: 接口、派遣接口和Variants三种方法之间的不同,在特定的环境中使用那种方法;

创建进程内和进程外COM自动化服务器; 
Vraiants在COM自动化服务器中的作用,以及如何使用容许后期连接到自动化对象; 
实现COM事件和回调; 
如何使用Delphi能相对轻松的使用ADO; 
知道接口、派遣接口、和Variants的区别。

 

第五章 ActiveX控件和ActiveForms
5.1 ActiveX控件
目的:

5.2 创建ActiveX控件;
目的:  

5.3 ActiveForm(Active窗体);
目的: 组件导向的中介软件;ActiveForm的开发;开发浏览器的客户端应用程序;

创建ActiveX工程:
New-->ActiveX-->ActiveX Library
New-->AcitveX-->Active Form
设计时期开发执照;
关于对话框;
版本控制编号;(一般要包括,控制新旧版本、以及是否从服务器下载);
分发:Project-->Web Deploy Options
Target dir: ActiveForm组件于HTML首页中codebase tag的目的;
Target URL: Delphi分发ActiveX组件的时候自动产生一个HTML的首页档案;
HTML dir: 储存这个HTML首页档案的位置;
Use CAB file compression:
Include file version number: 分发时包含版本信息;
Auto increment release number: 自动增加版本编号;
Deploy required package:
Deploy additional file:
project-->Wep deploy开始分发;
5.4 小结
目的:加强ActiveX组件的能力;
使用ActiveX组件; 
如何把已有组件转换为ActiveX组件;实现Delphi没有提供的功能; 
如何从窗体创建ActiveForm。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Delphi 10.3 是一个强大的开发环境,支持使用 COM 控件进行 Windows 应用程序开发。 COMComponent Object Model)是一种面向组件的软件架构模型,可以用于实现组件之间的通信和交互。COM 控件是使用 COM 技术开发的可复用的软件组件,可以在 Delphi 中轻松集成和使用。 在 Delphi 10.3 中使用 COM 控件非常简单。首先,需要在系统中注册 COM 控件。可以使用命令行工具 regsvr32 或者 Delphi IDE 中的 Tools 菜单下的 Register ActiveX Server 或者 Install Component 选项来注册 COM 控件。 注册完成后,在 Delphi 中添加一个 ActiveX 控件的实例,可以在 Components 菜单下的 Import Component 或者 Component Palette 中找到 COM 控件的安装向导。通过向导选择需要添加的控件,然后点击安装按钮,Delphi 会自动生成控件的包装类和代码。 一旦添加了 COM 控件的实例,就可以像使用其他 Delphi 控件一样对其进行操作。可以在代码中通过引用控件的属性、方法和事件来实现相应的功能。 Delphi 10.3 提供了一系列与 COM 控件相关的工具和组件,比如 TComObject 类和 ComObj 单元,可以帮助开发者更加便捷地使用和管理 COM 控件。 总而言之,Delphi 10.3 提供了强大的支持和便捷的工具,使开发者能够在 Windows 平台下高效地使用和集成 COM 控件,为应用程序的开发带来了很大的便利。 ### 回答2: Delphi 10.3是一款以Object Pascal为基础的软件开发环境,它包含了许多强大的功能和工具,可以用于开发各种类型的应用程序,包括使用COM控件进行开发。 COMComponent Object Model)是一种组件技术,它允许不同的应用程序之间进行通信和交互。Delphi 10.3提供了对COM控件的全面支持,开发人员可以使用它们来创建具有丰富功能和用户界面的应用程序使用Delphi 10.3开发COM控件的过程非常简单。首先,开发者需要使用Delphi的代码编辑器创建一个新的COM库项目。然后,可以在项目中添加所需的COM控件。Delphi 10.3提供了丰富的控件库,包括文本框、按钮、菜单等。开发人员可以通过拖放操作将这些控件添加到窗体上,并使用属性编辑器对其进行自定义设置。 一旦COM控件添加到窗体上,开发人员就可以使用Delphi的强大的代码编辑器编写代码来操作和控制这些控件。可以使用Delphi语言提供的各种功能和API来实现控件的各种操作,例如事件处理、数据绑定、图形绘制等。 Delphi 10.3还提供了一系列的调试工具,开发人员可以使用这些工具来调试和测试他们的应用程序。可以使用调试器来逐步执行代码,并观察代码的执行过程和变量的值。此外,还可以使用性能分析器来进行性能优化,以提高应用程序的运行效率。 综上所述,Delphi 10.3提供了强大而灵活的功能,使开发人员能够轻松地使用COM控件开发各种类型的应用程序。无论是开发桌面应用程序、Web应用程序还是移动应用程序Delphi 10.3都是一个强大的工具。 ### 回答3: Delphi 10.3是一个流行的开发工具,用于创建Windows应用程序组件。在Delphi 10.3中,COMComponent Object Model)是一种常用的技术,用于在不同的应用程序之间进行通信和交互。 COM控件是Delphi开发中常用的一种控件,它可以被其他应用程序调用和使用。通过COM控件,我们可以将一个Delphi应用程序暴露给其他编程语言(如C++、C#等),从而实现跨语言的开发和集成。 使用Delphi 10.3创建COM控件非常简单。首先,我们需要创建一个新的Delphi项目。然后,通过选择“File”菜单中的“New”和“Other”选项,从“Delphi Projects”文件夹中选择“ActiveX Library”,并设置相应的项目名称和保存位置。 在COM控件的代码中,我们可以定义接口和方法,以及属性和事件。通过接口定义,其他应用程序可以使用COM控件中的方法和属性。我们还可以使用GUID(全球唯一标识符)来标识COM控件,并在注册表中注册COM控件。 在编写COM控件代码后,我们需要编译并生成COM控件的DLL文件。然后,我们可以将该DLL文件注册到系统的注册表中,以便其他应用程序可以找到和使用COM控件。 在其他编程语言中,我们可以引用该COM控件并使用其中定义的方法和属性。例如,在C#中,我们可以使用“TypeLib Importer”工具生成一个代理类,并通过该代理类实例化COM控件,并调用其方法和属性。 总而言之,Delphi 10.3的COM控件是一种用于在不同的应用程序之间进行通信和交互的常用技术。通过创建COM控件,我们可以将Delphi应用程序暴露给其他编程语言,并实现跨语言的开发和集成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值