首先要注册COM,然后IMPORT到你的工程中来 然后USE 它的TLB文件然后定义接口 Var I_temp : IMyInterface; begin I_temp := coMyInterface.create; ... ...//后面就可以使用接口里定义的方法,属性了
end;
首先要注册COM,然后IMPORT到你的工程中来 然后USE 它的TLB文件然后定义接口 Var I_temp : IMyInterface; begin I_temp := coMyInterface.create; ... ...//后面就可以使用接口里定义的方法,属性了
end;
怎么注册COM呢? 又怎么生成TLB文件呢? 谢谢
他给出的COM接口名是什么,你用Interface替换什么 比如对方给出的COm接口中有一个ITest接口,你在程序中可以这样调用 var TMyTest:ITest; begin TMyTest:=CreateComObject(ITest); TMyTest.Methods//调用接口的方法 end;
xzhhai(星之瀚海) : 我是替换了报错:未定义的标识符:IWMEN
不好意思,前面写错了,如果对方给你的是com,那得看是那种类型的,如果是进程内的(dll/ocx)就用菜单中导入的功能,如果是进程外的,一运行它自己在系统中就注册了。再有 对于进程内的 uses //你的com的接口导入库Delphi自动可以生成 var TMyTest:coYourInterface begin TMyTest:=coYourInterface.Create; TMyTest.//提供的方法 end;进程外的 var TMyTest:YourInterface begin TMyTest:=CreateComObject(com类的唯一标识符) TMyTest.//提供的方法 end;
然后USE 它的TLB文件然后定义接口
Var
I_temp : IMyInterface;
begin
I_temp := coMyInterface.create;
...
...//后面就可以使用接口里定义的方法,属性了
end;
然后USE 它的TLB文件然后定义接口
Var
I_temp : IMyInterface;
begin
I_temp := coMyInterface.create;
...
...//后面就可以使用接口里定义的方法,属性了
end;
又怎么生成TLB文件呢?
谢谢
比如对方给出的COm接口中有一个ITest接口,你在程序中可以这样调用
var
TMyTest:ITest;
begin
TMyTest:=CreateComObject(ITest);
TMyTest.Methods//调用接口的方法
end;
我是替换了报错:未定义的标识符:IWMEN
对于进程内的
uses //你的com的接口导入库Delphi自动可以生成
var
TMyTest:coYourInterface
begin
TMyTest:=coYourInterface.Create;
TMyTest.//提供的方法
end;进程外的
var
TMyTest:YourInterface
begin
TMyTest:=CreateComObject(com类的唯一标识符)
TMyTest.//提供的方法
end;
第1章 在Delphi中使用接口:
1.1 定义接口:
目的:什么是接口,以及和抽象类的关联以及不同点。
抽象类(备注理解接口最简单的方法)
永远不能创建一个抽象类的实例;
本身不能实现功能,依靠派生类实现;
接口
被申明为interface类型。接口名从字母I开始。类类型名从T开始。
所有的接口从IUnknown继承;
不能创建接口实例;
不能在接口中指定范围指示。所有的方法都是公有型(public),不能在接口中申明包括范围指示;
不能申明变量;接口只能决定提供什么样的功能,对于如何完成功能没有限制。
接口中申明的所有函数和过程,概念上讲都是虚(virtual)抽象函数和过程。申明时不能带virtual;
接口是不变的;
1.2申明一个接口
目的:如何声明一个接口 GUID(Globally Unique Identifier)全球唯一标示符:CoCreateGuid产生(API)
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对象;
Enumer
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,comobj ;
type
TForm1 = class(TForm)
Button4: TButton;
Button5: TButton;
Button6: TButton;
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const
myid:TGUID= '{632B607F-BBC6-11D2-A329-006097C4E476}';
var
Form1: TForm1;
test:variant;
implementation{$R *.dfm}
procedure TForm1.Button5Click(Sender: TObject);
begin
test:=createcomobject(myid); //报错:‘类没有注册’
showmessage('ok');end;procedure TForm1.Button6Click(Sender: TObject);
begin
test:=null;
end;end.