Mega Code Archive

 
Categories / Delphi / Strings
 

Exposing a multi string object in COM

Title: Exposing a multi string object in COM Question: This document is intended for those using OLE/COM and want to expose a multi string object similar to Delphi's TStrings object. The IStrings interface for COM parallels the functionality of De Answer: The example project contains these units: Project1_TLB: A Pascal wrapper for the type library containing the interface definition. Unit1: The interface implementation containing storage for interface properties and code to implement interface methods. Unit2: The main form for the automation server. This unit is not strictly necessary, but provides feedback to know when methods have been successfully called AutCli: The automation client that obtains a reference to the interface and uses the interface methods. The general steps involved are listed below. You can compare each of these steps with the unit code that follows. 1) Create a type library and add an interface called IStr, with a single property called Items of type IStrings. See Developer's Guide, chapter 42 for more information on working with type libraries and creating interfaces in the type library editor. 2) In the previous step, adding an interface using the type library editor will cause a Pascal wrapper unit to be produced (in this example, the unit is called Unit1). Unit1 will contain shell implementations of get and set methods of the Items property. In this step you add implementation code to make the get and set methods functional. Also you need to add a method to create storage for your Items property, and to clean up that storage when the interface is no longer needed. Unit1 uses Unit2. Unit2 contains a form, memo and status bar to display status of each implemtation method, for diagnostic purposes. 3) Create Unit2 containing a form with TMemo and TStatusBar. The form is used to reflect activity in Unit1.pas. Though this step is not strictly necessary, it helps visualize what's happening between the automation client and server. 4) Create an automation client. In this case the unit is called AutCli and contains a memo component and two buttons that assign the Memo's TStrings data to the IStr interface's Items property. {--------------------------------------------------------------------} unit Project1_TLB; { This file contains pascal declarations imported from a type library. This file will be written during each import or refresh of the type library editor. Changes to this file will be discarded during the refresh process. } { Project1 Library } { Version 1.0 } interface uses Windows, ActiveX, Classes, Graphics, OleCtrls, StdVCL; const LIBID_Project1: TGUID = '{E6F9F3B6-FD3C-11D0-908F-00C04FC291A4}'; const { Component class GUIDs } Class_IStr: TGUID = '{E6F9F3B8-FD3C-11D0-908F-00C04FC291A4}'; type { Forward declarations: Interfaces } IIStr = interface; IIStrDisp = dispinterface; { Forward declarations: CoClasses } IStr = IIStr; { Dispatch interface for IStr Object } IIStr = interface(IDispatch) ['{E6F9F3B7-FD3C-11D0-908F-00C04FC291A4}'] function Get_Items: IStrings; safecall; procedure Set_Items(const Value: IStrings); safecall; property Items: IStrings read Get_Items write Set_Items; end; { DispInterface declaration for Dual Interface IIStr } IIStrDisp = dispinterface ['{E6F9F3B7-FD3C-11D0-908F-00C04FC291A4}'] property Items: IStrings dispid 1; end; { IStrObject } CoIStr = class class function Create: IIStr; class function CreateRemote(const MachineName: string): IIStr; end; implementation uses ComObj; class function CoIStr.Create: IIStr; begin Result := CreateComObject(Class_IStr) as IIStr; end; class function CoIStr.CreateRemote(const MachineName: string): IIStr; begin Result := CreateRemoteComObject(MachineName, Class_IStr) as IIStr; end; end. {--------------------------------------------------------------------} unit Unit1; interface uses ComObj, Project1_TLB, StdVCL, Classes, AxCtrls, Unit2; type TIStr = class(TAutoObject, IIStr) private FItems: TStrings; public destructor Destroy; override; procedure Initialize; override; function Get_Items: IStrings; safecall; procedure Set_Items(const Value: IStrings); safecall; end; implementation uses ComServ, Dialogs; procedure TIStr.Initialize; begin Inherited Initialize; FItems := TStringList.Create; end; destructor TIStr.Destroy; begin FItems.Free; end; function TIStr.Get_Items: IStrings; begin Form1.Memo1.Lines.Assign(FItems); GetOleStrings(FItems, Result); Form1.StatusBar1.SimpleText := 'TIStr.Get_Items: IStrings'; end; procedure TIStr.Set_Items(const Value: IStrings); begin SetOleStrings(FItems, Value); Form1.Memo1.Lines.Assign(FItems); Form1.StatusBar1.SimpleText := 'TIStr.Set_Items(const Value: IStrings)'; end; initialization TAutoObjectFactory.Create(ComServer, TIStr, Class_IStr, ciMultiInstance