├── .gitignore ├── LICENSE ├── LazComDll ├── LazComDll.lpi ├── LazComDll.lpr ├── LazComDll.lps ├── LazComDll.ridl ├── LazComDll.tlb ├── lazcomlib_1_0_tlb.pas └── lazcomunit.pas ├── LazComDllApp ├── LazComDllApp.lpi ├── LazComDllApp.lpr ├── LazComDllApp.lps ├── comobjunit.pas ├── lazcomlib_1_0_tlb.pas └── mainunit.pas └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | __history 2 | backup 3 | /LazComDll/lib 4 | /LazComDll/LazComDll.dll 5 | /LazComDllApp/lib 6 | /LazComDllApp/LazComDllApp.exe 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 MartinTrummer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /LazComDll/LazComDll.lpi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | <UseAppBundle Value="False"/> 15 | <ResourceType Value="res"/> 16 | </General> 17 | <i18n> 18 | <EnableI18N LFM="False"/> 19 | </i18n> 20 | <VersionInfo> 21 | <StringTable ProductVersion=""/> 22 | </VersionInfo> 23 | <BuildModes Count="1"> 24 | <Item1 Name="Default" Default="True"/> 25 | </BuildModes> 26 | <PublishOptions> 27 | <Version Value="2"/> 28 | </PublishOptions> 29 | <RunParams> 30 | <local> 31 | <FormatVersion Value="1"/> 32 | </local> 33 | </RunParams> 34 | <Units Count="4"> 35 | <Unit0> 36 | <Filename Value="LazComDll.lpr"/> 37 | <IsPartOfProject Value="True"/> 38 | <UnitName Value="LazComDll"/> 39 | </Unit0> 40 | <Unit1> 41 | <Filename Value="lazcomlib_1_0_tlb.pas"/> 42 | <IsPartOfProject Value="True"/> 43 | <UnitName Value="LazComLib_1_0_TLB"/> 44 | </Unit1> 45 | <Unit2> 46 | <Filename Value="lazcomunit.pas"/> 47 | <IsPartOfProject Value="True"/> 48 | <UnitName Value="LazComUnit"/> 49 | </Unit2> 50 | <Unit3> 51 | <Filename Value="..\LazComDllApp\mainunit.pas"/> 52 | <IsPartOfProject Value="True"/> 53 | <UnitName Value="MainUnit"/> 54 | </Unit3> 55 | </Units> 56 | </ProjectOptions> 57 | <CompilerOptions> 58 | <Version Value="11"/> 59 | <PathDelim Value="\"/> 60 | <Target> 61 | <Filename Value="LazComDll"/> 62 | </Target> 63 | <SearchPaths> 64 | <IncludeFiles Value="$(ProjOutDir)"/> 65 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 66 | </SearchPaths> 67 | <CodeGeneration> 68 | <RelocatableUnit Value="True"/> 69 | </CodeGeneration> 70 | <Linking> 71 | <Options> 72 | <ExecutableType Value="Library"/> 73 | </Options> 74 | </Linking> 75 | <Other> 76 | <CompilerMessages> 77 | <MsgFileName Value=""/> 78 | </CompilerMessages> 79 | <CompilerPath Value="$(CompPath)"/> 80 | </Other> 81 | </CompilerOptions> 82 | <Debugging> 83 | <Exceptions Count="3"> 84 | <Item1> 85 | <Name Value="EAbort"/> 86 | </Item1> 87 | <Item2> 88 | <Name Value="ECodetoolError"/> 89 | </Item2> 90 | <Item3> 91 | <Name Value="EFOpenError"/> 92 | </Item3> 93 | </Exceptions> 94 | </Debugging> 95 | </CONFIG> 96 | -------------------------------------------------------------------------------- /LazComDll/LazComDll.lpr: -------------------------------------------------------------------------------- 1 | library LazComDll; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | uses 6 | Classes 7 | { you can add units after this } 8 | , LazComLib_1_0_TLB 9 | , ComServ, LazComUnit; 10 | 11 | {$R *.TLB} 12 | 13 | exports 14 | DllGetClassObject, 15 | DllCanUnloadNow, 16 | DllRegisterServer, 17 | DllUnregisterServer; 18 | 19 | begin 20 | 21 | end. 22 | 23 | -------------------------------------------------------------------------------- /LazComDll/LazComDll.lps: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectSession> 4 | <PathDelim Value="\"/> 5 | <Version Value="9"/> 6 | <BuildModes Active="Default"/> 7 | <Units Count="4"> 8 | <Unit0> 9 | <Filename Value="LazComDll.lpr"/> 10 | <IsPartOfProject Value="True"/> 11 | <UnitName Value="LazComDll"/> 12 | <WindowIndex Value="0"/> 13 | <TopLine Value="1"/> 14 | <CursorPos X="24" Y="9"/> 15 | <UsageCount Value="21"/> 16 | </Unit0> 17 | <Unit1> 18 | <Filename Value="lazcomlib_1_0_tlb.pas"/> 19 | <IsPartOfProject Value="True"/> 20 | <UnitName Value="LazComLib_1_0_TLB"/> 21 | <WindowIndex Value="0"/> 22 | <TopLine Value="4"/> 23 | <CursorPos X="22" Y="18"/> 24 | <UsageCount Value="21"/> 25 | </Unit1> 26 | <Unit2> 27 | <Filename Value="lazcomunit.pas"/> 28 | <IsPartOfProject Value="True"/> 29 | <UnitName Value="LazComUnit"/> 30 | <IsVisibleTab Value="True"/> 31 | <WindowIndex Value="0"/> 32 | <TopLine Value="1"/> 33 | <CursorPos X="44" Y="17"/> 34 | <UsageCount Value="21"/> 35 | </Unit2> 36 | <Unit3> 37 | <Filename Value="..\LazComDllApp\mainunit.pas"/> 38 | <IsPartOfProject Value="True"/> 39 | <UnitName Value="MainUnit"/> 40 | <WindowIndex Value="0"/> 41 | <TopLine Value="1"/> 42 | <CursorPos X="1" Y="1"/> 43 | <UsageCount Value="21"/> 44 | </Unit3> 45 | </Units> 46 | <JumpHistory Count="0" HistoryIndex="-1"/> 47 | </ProjectSession> 48 | <EditorMacros Count="0"/> 49 | </CONFIG> 50 | -------------------------------------------------------------------------------- /LazComDll/LazComDll.ridl: -------------------------------------------------------------------------------- 1 | // ************************************************************************ // 2 | // WARNING 3 | // ------- 4 | // This file is generated by the Type Library importer or Type Libary Editor. 5 | // Barring syntax errors, the Editor will parse modifications made to the file. 6 | // However, when applying changes via the Editor this file will be regenerated 7 | // and comments or formatting changes will be lost. 8 | // ************************************************************************ // 9 | // File generated on 19/11/2014 15:56:50 (- $Rev: 12980 $, 23204571). 10 | 11 | [ 12 | uuid(570A55B0-1122-49AE-A335-1F630EC4FE65), 13 | version(1.0) 14 | 15 | ] 16 | library LazComLib 17 | { 18 | 19 | importlib("stdole2.tlb"); 20 | 21 | interface ILazCom; 22 | coclass LazComCoClass; 23 | 24 | 25 | [ 26 | uuid(247EAD48-16D6-4C1C-9265-F841BF4BD411), 27 | dual, 28 | oleautomation 29 | ] 30 | interface ILazCom: IDispatch 31 | { 32 | }; 33 | 34 | [ 35 | uuid(C5B9D6F8-76A4-4D4A-A40C-CA718637C07B) 36 | ] 37 | coclass LazComCoClass 38 | { 39 | [default] interface ILazCom; 40 | }; 41 | 42 | }; 43 | -------------------------------------------------------------------------------- /LazComDll/LazComDll.tlb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MartinTrummer/lazarus-com-example/9db9ad7dbfdcbcc0d82db05b31fea2473b78f9c5/LazComDll/LazComDll.tlb -------------------------------------------------------------------------------- /LazComDll/lazcomlib_1_0_tlb.pas: -------------------------------------------------------------------------------- 1 | Unit LazComLib_1_0_TLB; 2 | 3 | // Imported LazComLib on 19/11/2014 15:59:16 from D:\_development\Lazarus\LazComDll\LazComDll.tlb 4 | 5 | {$mode delphi}{$H+} 6 | 7 | interface 8 | 9 | Uses 10 | Windows,ActiveX,Classes,Variants; 11 | Const 12 | LazComLibMajorVersion = 1; 13 | LazComLibMinorVersion = 0; 14 | LazComLibLCID = 0; 15 | LIBID_LazComLib : TGUID = '{570A55B0-1122-49AE-A335-1F630EC4FE65}'; 16 | 17 | IID_ILazCom : TGUID = '{247EAD48-16D6-4C1C-9265-F841BF4BD411}'; 18 | CLASS_LazComCoClass : TGUID = '{93E11168-E984-415C-ACD6-853226D22CF9}'; 19 | 20 | //Enums 21 | 22 | //Forward declarations 23 | 24 | Type 25 | ILazCom = interface; 26 | ILazComDisp = dispinterface; 27 | 28 | //Map CoClass to its default interface 29 | 30 | LazComCoClass = ILazCom; 31 | 32 | //records, unions, aliases 33 | 34 | 35 | //interface declarations 36 | 37 | // ILazCom : 38 | 39 | ILazCom = interface(IDispatch) 40 | ['{247EAD48-16D6-4C1C-9265-F841BF4BD411}'] 41 | // LazComMethod : 42 | procedure LazComMethod;safecall; 43 | end; 44 | 45 | 46 | // ILazCom : 47 | 48 | ILazComDisp = dispinterface 49 | ['{247EAD48-16D6-4C1C-9265-F841BF4BD411}'] 50 | // LazComMethod : 51 | procedure LazComMethod;dispid 201; 52 | end; 53 | 54 | //CoClasses 55 | CoLazComCoClass = Class 56 | Public 57 | Class Function Create: ILazCom; 58 | Class Function CreateRemote(const MachineName: string): ILazCom; 59 | end; 60 | 61 | implementation 62 | 63 | uses comobj; 64 | 65 | Class Function CoLazComCoClass.Create: ILazCom; 66 | begin 67 | Result := CreateComObject(CLASS_LazComCoClass) as ILazCom; 68 | end; 69 | 70 | Class Function CoLazComCoClass.CreateRemote(const MachineName: string): ILazCom; 71 | begin 72 | Result := CreateRemoteComObject(MachineName,CLASS_LazComCoClass) as ILazCom; 73 | end; 74 | 75 | end. 76 | -------------------------------------------------------------------------------- /LazComDll/lazcomunit.pas: -------------------------------------------------------------------------------- 1 | unit LazComUnit; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | ComObj, LazComLib_1_0_TLB; 9 | 10 | type 11 | 12 | { TLazCom } 13 | TLazCom = class(TAutoObject, ILazCom) 14 | public 15 | procedure LazComMethod;safecall; 16 | end; 17 | 18 | implementation 19 | 20 | uses 21 | comserv; 22 | 23 | { TLazCom } 24 | 25 | procedure TLazCom.LazComMethod; safecall; 26 | begin 27 | WriteLn('LazComMethod called'); 28 | end; 29 | 30 | 31 | initialization 32 | TAutoObjectFactory.Create(ComServer, TLazCom, CLASS_LazComCoClass, 33 | ciMultiInstance, tmApartment); 34 | 35 | end. 36 | 37 | -------------------------------------------------------------------------------- /LazComDllApp/LazComDllApp.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="9"/> 5 | <PathDelim Value="\"/> 6 | <General> 7 | <Flags> 8 | <MainUnitHasCreateFormStatements Value="False"/> 9 | </Flags> 10 | <SessionStorage Value="InProjectDir"/> 11 | <MainUnit Value="0"/> 12 | <Title Value="Lazarus Com Dll App"/> 13 | <UseAppBundle Value="False"/> 14 | <ResourceType Value="res"/> 15 | </General> 16 | <i18n> 17 | <EnableI18N LFM="False"/> 18 | </i18n> 19 | <VersionInfo> 20 | <StringTable ProductVersion=""/> 21 | </VersionInfo> 22 | <BuildModes Count="1"> 23 | <Item1 Name="Default" Default="True"/> 24 | </BuildModes> 25 | <PublishOptions> 26 | <Version Value="2"/> 27 | </PublishOptions> 28 | <RunParams> 29 | <local> 30 | <FormatVersion Value="1"/> 31 | </local> 32 | </RunParams> 33 | <Units Count="3"> 34 | <Unit0> 35 | <Filename Value="LazComDllApp.lpr"/> 36 | <IsPartOfProject Value="True"/> 37 | <UnitName Value="LazComDllApp"/> 38 | </Unit0> 39 | <Unit1> 40 | <Filename Value="comobjunit.pas"/> 41 | <IsPartOfProject Value="True"/> 42 | <UnitName Value="ComObjUnit"/> 43 | </Unit1> 44 | <Unit2> 45 | <Filename Value="lazcomlib_1_0_tlb.pas"/> 46 | <IsPartOfProject Value="True"/> 47 | <UnitName Value="LazComLib_1_0_TLB"/> 48 | </Unit2> 49 | </Units> 50 | </ProjectOptions> 51 | <CompilerOptions> 52 | <Version Value="11"/> 53 | <PathDelim Value="\"/> 54 | <Target> 55 | <Filename Value="LazComDllApp"/> 56 | </Target> 57 | <SearchPaths> 58 | <IncludeFiles Value="$(ProjOutDir)"/> 59 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 60 | </SearchPaths> 61 | <Other> 62 | <CompilerMessages> 63 | <MsgFileName Value=""/> 64 | </CompilerMessages> 65 | <CompilerPath Value="$(CompPath)"/> 66 | </Other> 67 | </CompilerOptions> 68 | <Debugging> 69 | <Exceptions Count="3"> 70 | <Item1> 71 | <Name Value="EAbort"/> 72 | </Item1> 73 | <Item2> 74 | <Name Value="ECodetoolError"/> 75 | </Item2> 76 | <Item3> 77 | <Name Value="EFOpenError"/> 78 | </Item3> 79 | </Exceptions> 80 | </Debugging> 81 | </CONFIG> 82 | -------------------------------------------------------------------------------- /LazComDllApp/LazComDllApp.lpr: -------------------------------------------------------------------------------- 1 | program LazComDllApp; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | uses 6 | {$IFDEF UNIX}{$IFDEF UseCThreads} 7 | cthreads, 8 | {$ENDIF}{$ENDIF} 9 | Classes, SysUtils, CustApp, ComObjUnit, LazComLib_1_0_TLB 10 | { you can add units after this }; 11 | 12 | type 13 | 14 | { TLazComDll } 15 | 16 | TLazComDll = class(TCustomApplication) 17 | protected 18 | procedure DoRun; override; 19 | public 20 | constructor Create(TheOwner: TComponent); override; 21 | destructor Destroy; override; 22 | procedure WriteHelp; virtual; 23 | end; 24 | 25 | { TLazComDll } 26 | 27 | procedure TLazComDll.DoRun; 28 | var 29 | ErrorMsg: String; 30 | begin 31 | // quick check parameters 32 | ErrorMsg:=CheckOptions('h','help'); 33 | if ErrorMsg<>'' then begin 34 | ShowException(Exception.Create(ErrorMsg)); 35 | Terminate; 36 | Exit; 37 | end; 38 | 39 | // parse parameters 40 | if HasOption('h','help') then begin 41 | WriteHelp; 42 | Terminate; 43 | Exit; 44 | end; 45 | 46 | UseComObj(); 47 | 48 | // stop program loop 49 | Terminate; 50 | end; 51 | 52 | constructor TLazComDll.Create(TheOwner: TComponent); 53 | begin 54 | inherited Create(TheOwner); 55 | StopOnException:=True; 56 | end; 57 | 58 | destructor TLazComDll.Destroy; 59 | begin 60 | inherited Destroy; 61 | end; 62 | 63 | procedure TLazComDll.WriteHelp; 64 | begin 65 | { add your help code here } 66 | writeln('Usage: ',ExeName,' -h'); 67 | end; 68 | 69 | var 70 | Application: TLazComDll; 71 | begin 72 | Application:=TLazComDll.Create(nil); 73 | Application.Title:='Lazarus Com Dll App'; 74 | Application.Run; 75 | Application.Free; 76 | end. 77 | 78 | -------------------------------------------------------------------------------- /LazComDllApp/LazComDllApp.lps: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectSession> 4 | <PathDelim Value="\"/> 5 | <Version Value="9"/> 6 | <BuildModes Active="Default"/> 7 | <Units Count="3"> 8 | <Unit0> 9 | <Filename Value="LazComDllApp.lpr"/> 10 | <IsPartOfProject Value="True"/> 11 | <UnitName Value="LazComDllApp"/> 12 | <EditorIndex Value="0"/> 13 | <WindowIndex Value="0"/> 14 | <TopLine Value="33"/> 15 | <CursorPos X="15" Y="46"/> 16 | <UsageCount Value="20"/> 17 | <Loaded Value="True"/> 18 | </Unit0> 19 | <Unit1> 20 | <Filename Value="comobjunit.pas"/> 21 | <IsPartOfProject Value="True"/> 22 | <UnitName Value="ComObjUnit"/> 23 | <IsVisibleTab Value="True"/> 24 | <EditorIndex Value="1"/> 25 | <WindowIndex Value="0"/> 26 | <TopLine Value="1"/> 27 | <CursorPos X="16" Y="1"/> 28 | <UsageCount Value="20"/> 29 | <Loaded Value="True"/> 30 | </Unit1> 31 | <Unit2> 32 | <Filename Value="lazcomlib_1_0_tlb.pas"/> 33 | <IsPartOfProject Value="True"/> 34 | <UnitName Value="LazComLib_1_0_TLB"/> 35 | <EditorIndex Value="2"/> 36 | <WindowIndex Value="0"/> 37 | <TopLine Value="29"/> 38 | <CursorPos X="18" Y="55"/> 39 | <UsageCount Value="20"/> 40 | <Loaded Value="True"/> 41 | </Unit2> 42 | </Units> 43 | <General> 44 | <ActiveWindowIndexAtStart Value="0"/> 45 | </General> 46 | <JumpHistory Count="0" HistoryIndex="-1"/> 47 | </ProjectSession> 48 | <EditorMacros Count="0"/> 49 | </CONFIG> 50 | -------------------------------------------------------------------------------- /LazComDllApp/comobjunit.pas: -------------------------------------------------------------------------------- 1 | unit ComObjUnit; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils, LazComLib_1_0_TLB; 9 | 10 | procedure UseComObj(); 11 | 12 | implementation 13 | 14 | procedure UseComObj(); 15 | var 16 | LazCom: ILazCom; 17 | begin 18 | WriteLn('creating the com object'); 19 | LazCom := CoLazComCoClass.Create(); 20 | WriteLn('calling the com method:'); 21 | LazCom.LazComMethod(); 22 | WriteLn('done'); 23 | end; 24 | 25 | end. 26 | 27 | -------------------------------------------------------------------------------- /LazComDllApp/lazcomlib_1_0_tlb.pas: -------------------------------------------------------------------------------- 1 | Unit LazComLib_1_0_TLB; 2 | 3 | // Imported LazComLib on 19/11/2014 16:19:46 from D:\_development\Lazarus\LazComDll\LazComDll.dll 4 | 5 | {$mode delphi}{$H+} 6 | 7 | interface 8 | 9 | Uses 10 | Windows,ActiveX,Classes,Variants; 11 | Const 12 | LazComLibMajorVersion = 1; 13 | LazComLibMinorVersion = 0; 14 | LazComLibLCID = 0; 15 | LIBID_LazComLib : TGUID = '{570A55B0-1122-49AE-A335-1F630EC4FE65}'; 16 | 17 | IID_ILazCom : TGUID = '{247EAD48-16D6-4C1C-9265-F841BF4BD411}'; 18 | CLASS_LazComCoClass : TGUID = '{93E11168-E984-415C-ACD6-853226D22CF9}'; 19 | 20 | //Enums 21 | 22 | //Forward declarations 23 | 24 | Type 25 | ILazCom = interface; 26 | ILazComDisp = dispinterface; 27 | 28 | //Map CoClass to its default interface 29 | 30 | LazComCoClass = ILazCom; 31 | 32 | //records, unions, aliases 33 | 34 | 35 | //interface declarations 36 | 37 | // ILazCom : 38 | 39 | ILazCom = interface(IDispatch) 40 | ['{247EAD48-16D6-4C1C-9265-F841BF4BD411}'] 41 | // LazComMethod : 42 | procedure LazComMethod;safecall; 43 | end; 44 | 45 | 46 | // ILazCom : 47 | 48 | ILazComDisp = dispinterface 49 | ['{247EAD48-16D6-4C1C-9265-F841BF4BD411}'] 50 | // LazComMethod : 51 | procedure LazComMethod;dispid 201; 52 | end; 53 | 54 | //CoClasses 55 | CoLazComCoClass = Class 56 | Public 57 | Class Function Create: ILazCom; 58 | Class Function CreateRemote(const MachineName: string): ILazCom; 59 | end; 60 | 61 | implementation 62 | 63 | uses comobj; 64 | 65 | Class Function CoLazComCoClass.Create: ILazCom; 66 | begin 67 | Result := CreateComObject(CLASS_LazComCoClass) as ILazCom; 68 | end; 69 | 70 | Class Function CoLazComCoClass.CreateRemote(const MachineName: string): ILazCom; 71 | begin 72 | Result := CreateRemoteComObject(MachineName,CLASS_LazComCoClass) as ILazCom; 73 | end; 74 | 75 | end. 76 | -------------------------------------------------------------------------------- /LazComDllApp/mainunit.pas: -------------------------------------------------------------------------------- 1 | unit MainUnit; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils; 9 | 10 | implementation 11 | 12 | end. 13 | 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | lazarus-com-example 2 | =================== 3 | 4 | example project to test COM programming in the Lazarus IDE 5 | 6 | # Goal 7 | The goal of this example is to document how you can use the free Lazarus IDE to create a DLL that contains a COM object and its type library. So that you can use the COM object easily: i.e. use regsvr32 to register the COM object, read the type library from the DLL and thus use the COM object in any application. 8 | 9 | We will build 2 projects: 10 | 11 | 1. Dll Project (LazComDll): this project will create the DLL file that includes the COM object 12 | 2. Exe Project (LazComDllApp): this project will create an EXE file which will use the registered COM object (in the DLL) and call a method on it 13 | 14 | ## System description 15 | - Windows® 7 SP1 64 bit 16 | - Lazarus IDE 32 bit: http://www.lazarus.freepascal.org/ 17 | - Version #: 1.2.6 18 | - Date: 2014-10-11 19 | - FPC: Version 2.6.4 20 | - SVN Revision: 46529 21 | - i386-win32-win32/win64 22 | - LazActiveX: http://wiki.lazarus.freepascal.org/LazActiveX/ 23 | - required to import type libraries 24 | 25 | ## Dll Project 26 | ### Type Library 27 | The first thing that we need is the type library. I could not find out how to build a type library in Lazarus, thus I have created one in Delphi (Does anyone know a simpler alternative or even a Lazarus extension?) 28 | 29 | In Delphi it is easy to define the type library in a RIDL file and then generated the <a href="LazComDll/LazComDll.ridl">type library file</a> 30 | 31 | ### Crate Lazarus Library Project 32 | The next step is to build a Lazarus project which will finally create a DLL file: File - New - Project - Library 33 | 34 | ### Import the type library 35 | Now we import the type library file: Tools - Import Type Library - select the *.tlb file. 36 | Lazarus will then create a new pascal file based on the definitions of the type library file. 37 | 38 | ### Include the type library as a resource in the DLL 39 | We want that the created DLL file includes the type library file as a resource, so that other programs can read and use the type library. This is easy to do in free Pascal: In the Lazarus project file, include the type library file as a resource: 40 | ```pascal 41 | {$R *.TLB} 42 | ``` 43 | 44 | ### Export Functions 45 | In the same file, we will now define the functions that the DLL exports, so that users of the DLL can use the regsvr32.exe utility to register the COM object. 46 | - add ComServ to the uses clause 47 | - export the following functions: 48 | ```pascal 49 | exports 50 | DllGetClassObject, 51 | DllCanUnloadNow, 52 | DllRegisterServer, 53 | DllUnregisterServer; 54 | ``` 55 | 56 | ### Implement the ComObject 57 | Now that the basic plumbing is done, we can implement the ComObject. In Lazarus: File - New - Unit: `LazComUnit` 58 | 59 | We keep it as simple as possible. The class is called `TLazCom` and it inherits from `TAutoObject` (in the ComObj unit) and implements the COM interface `ILazCom` that is defined in the type library: The one and only method of this interface/class will print a message to stdout. 60 | 61 | ```pascal 62 | uses 63 | ComObj, LazComLib_1_0_TLB; 64 | 65 | type 66 | { TLazCom } 67 | TLazCom = class(TAutoObject, ILazCom) 68 | public 69 | procedure LazComMethod;safecall; 70 | end; 71 | 72 | implementation 73 | 74 | { TLazCom } 75 | 76 | procedure TLazCom.LazComMethod; safecall; 77 | begin 78 | WriteLn('LazComMethod called'); 79 | end; 80 | ``` 81 | 82 | ### Create the Object Factory 83 | In the initialization part of the file, we will create the Object Factory (note: you must add `ComServ` to the uses list): 84 | 85 | ```pascal 86 | initialization 87 | TAutoObjectFactory.Create(ComServer, TLazCom, CLASS_LazComCoClass, 88 | ciMultiInstance, tmApartment); 89 | ``` 90 | 91 | ### Build the DLL 92 | In Lazarus: Run - Build 93 | That's it: now we have a DLL that includes the type library and the implentation of our COM object. The DLL also exports some functions that can be used by the regsvr32 utility to register the COM object in the Windows® Registry. 94 | 95 | #### Register the COM object 96 | In a Windows® command prompt go to the directory where the DLL file is located and run the regsvr32 utility like this: 97 | ```Batchfile 98 | regsvr32 LazComDll.dll 99 | ``` 100 | You should see an information message box saying: `DllRegisterServer in LazComDll.dll succeeded.` 101 | 102 | ## Exe Project 103 | The Exe project will be a simple console application. 104 | 105 | ### Create the console application 106 | In Lazarus: File - New… - Console Application 107 | 108 | ### Import the type library 109 | Now we import the type library file: Tools - Import Type Library - select our `LazComDll.dll` file (which includes the type library). 110 | Lazarus will then create a new pascal file based on the definitions of the type library file. 111 | 112 | ### Using the COM Object 113 | Create a new unit that will instantiate the COM object: In Lazarus: File - New - Unit: `ComObjUnit` 114 | 115 | ```pascal 116 | uses 117 | Classes, SysUtils, LazComLib_1_0_TLB; 118 | 119 | procedure UseComObj(); 120 | 121 | implementation 122 | 123 | procedure UseComObj(); 124 | var 125 | LazCom: ILazCom; 126 | begin 127 | WriteLn('creating the com object'); 128 | LazCom := CoLazComCoClass.Create(); 129 | WriteLn('calling the com method:'); 130 | LazCom.LazComMethod(); 131 | WriteLn('done'); 132 | end; 133 | ``` 134 | 135 | ### Execute the application 136 | In the console application project file, we call our function like this: 137 | ```pascal 138 | UseComObj(); 139 | ``` 140 | 141 | then build the project: Run - Build 142 | 143 | And start the exe in a Winodws® command prompt. You should see this output: 144 | ``` 145 | creating the com object 146 | calling the com method: 147 | LazComMethod called 148 | done 149 | ``` 150 | 151 | ---- 152 | this document was created with the haroo-pad markdown editor: http://pad.haroopress.com/ 153 | --------------------------------------------------------------------------------