¿Como crear un objeto COM?



Las interfaces pueden utilizarse como una técnica de programación más. La misma aplicación puede definir las interfaces, crear las clases que la implementan y manejar internamente sus propios objetos. Sin embargo, lo habitual es que el cliente que utiliza un objeto y el servidor que lo define e implementa sean módulos diferentes. Para que una aplicación pueda crear un objeto definido en otro módulo, sea ejecutable o DLL, necesitamos funciones y procedimientos definidos por COM.

La función más sencilla que permite crear un objeto Com es:
 

 Function CreateComObject(constClassID:TGUID): Iunknown;

Otra posibilidad es utilizar:
 

 Function CreateRemoteComObject(constMachineName:widestring;constclassID:TGUID):Iunknown;

Esta vez COM busca la información de la clase indicada en el registro de otra máquina, crea el objeto basado en la clase en el espacio de direcciones de ese ordenador, y devuelve nuevamente un "puntero" al objeto creado.

Para que las aplicaciones clientes puedan sacar provecho de los servidores, estos últimos deben registrarse en algún lugar. Este lugar es el registro de configuraciones. Los datos acerca de servidores COM se guardan bajo la clave HKEY_CLASSES_ROOT. Cuando una aplicación cliente pide la creación de un objeto COM, para ello utiliza la función CreateComObject.

¿Que ocurre cuando una aplicación cliente pide la creación de un objeto COM?. Hay que comenzar examinando la creación, para ello se utiliza CreateComObject:
 

 var
   Interfaz1:Iunknown;
 Begin
   Interfaz1:=createcomobject(CLSID_Semaforo);
 end;

El identificador de la clase se busca en la clave CLSID de la raíz de las clases del registro. Dentro de la misma, nos dice que el servidor es una aplicación local y obtenemos su nombre y su ruta, para ejecutarla. Com crea el objeto y devuelve un puntero a su interfaz IUNKnown principal a la aplicación cliente. Sin embargo, es bastante incómodo tener que trabajar con los identificadores globales de clase, por lo que la mayoría de los servidores definen un nombre "legible" para las clases que implementan. En la jerga de COM, a estos nombres se les conoce como identificadores de programa. En concreto, la función CreateOleObject

Veamos el primer ejemplo con objetos COM. Crearemos un objeto con dos propiedades y una función, para ello entramos en la librería de tipos y pulsando con el botón derecho del ratón en el interface del objeto elegimos property y método. El objeto lo que hace es realizar la multiplicación de dos valores introducidos desde nuestra aplicación. A continuación se incluye el código de creación y utilización del objeto:

1º.- Para crear la librería entramos en File/New y en la pestaña ActiveX elegimos ActiveX Library. Obtenemos el siguiente resultado:
 

 library Pruebacom;

 uses
   ComServ,
   Pruebacom_TLB in 'Pruebacom_TLB.pas',
   Unit1 in 'Unit1.pas' {Multiple: CoClass};

 exports
   DllGetClassObject,
   DllCanUnloadNow,
   DllRegisterServer,
   DllUnregisterServer;

 {$R *.TLB}

 {$R *.RES}

 begin
 end.

2º .- A continuación incluimos en la librería el objeto, para ello entramos en File/new y en la pestaña ActiveX elegimos Automation Object. Nos pide el nombre para la clase que creara dentro de la librería de tipos, además creara también un interface para el objeto. Después lo que tenemos que hacer es crear las propiedades y métodos para el objeto. En nuestro caso creamos dos propiedades y una función que será la que devolvera la múltiplicación de los dos valores que introduzcamos desde nuestra aplicación. Para crear las propiedades y métodos entramos en view/type library y pinchamos con el botón derecho en el interface y elegimos property y method.Al añadir una nueva propiedad obtenemos la siguiente pantalla.

 unit Unit1;

 interface

 uses
   Windows, ActiveX, ComObj, Pruebacom_TLB;

 type
   TMultiple = class(TTypedComObject, IMultiple)
   private
     FX:Integer;
     FY:integer;
   protected
     function DOIT: Integer; stdcall;
     function Get_x: Integer; stdcall;
     function Get_y: Integer; stdcall;
     procedure Set_x(Value: Integer); stdcall;
     procedure Set_y(Value: Integer); stdcall;
     {Declare IMultiple methods here}
   end;

 implementation

 uses ComServ;

 function TMultiple.DOIT: Integer;
 begin
   result:=fx+fy;
 end;

 function TMultiple.Get_x: Integer;
 begin
   result:=FX;
 end;

 function TMultiple.Get_y: Integer;
 begin
   result:=fy;
 end;

 procedure TMultiple.Set_x(Value: Integer);
 begin
   fx:=value;
 end;

 procedure TMultiple.Set_y(Value: Integer);
 begin
   fy:=value;
 end;

 initialization
   TTypedComObjectFactory.Create(ComServer, TMultiple, Class_Multiple,
    ciMultiInstance, tmSingle);
 end.

Si deseamos ver la librería de tipos entramos en View/Type Library. Para ver el código generado podemos entrar en código fuente

A continuación se incluye el código de la aplicación que utiliza dicho objeto:

unit utilcom1;

 interface

 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   StdCtrls,comobj,pruebacom_tlb;

 type
   TForm1 = class(TForm)
     Label1: TLabel;
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
   end;

 var
   Form1: TForm1;

 implementation

 {$R *.DFM}

 procedure TForm1.Button1Click(Sender: TObject);
 var
  sum:IMultiple;
 begin
  //creamos un puntero al interfaz IMultiple pasando
  //el nombre del identificador
  sum:=CreateComObject(CLASS_Multiple) as IMultiple;
   if assigned(sum) then begin
    //llamamos a sus métodos
    sum.set_x(20);
    sum.set_y(20);
    //llamamos a la función doit 
    label1.caption:=inttostr(sum.doit);
  end;
 end;
 end.

Ejemplo


(C) 1999 Database DM. la reproduccion total o parcial de este documento, asi como la dibulgacion de parte o la totalidad