Browse Source

* StdOle2 and typelib added from Ludo Brands (bug 20958)

git-svn-id: trunk@19887 -
michael 13 years ago
parent
commit
4c8800c253

+ 2 - 0
.gitattributes

@@ -6500,7 +6500,9 @@ packages/winunits-base/src/richedit.pp svneol=native#text/plain
 packages/winunits-base/src/shellapi.pp svneol=native#text/plain
 packages/winunits-base/src/shellapi.pp svneol=native#text/plain
 packages/winunits-base/src/shfolder.pp svneol=native#text/plain
 packages/winunits-base/src/shfolder.pp svneol=native#text/plain
 packages/winunits-base/src/shlobj.pp svneol=native#text/plain
 packages/winunits-base/src/shlobj.pp svneol=native#text/plain
+packages/winunits-base/src/stdole2.pas svneol=native#text/plain
 packages/winunits-base/src/tmschema.inc svneol=native#text/plain
 packages/winunits-base/src/tmschema.inc svneol=native#text/plain
+packages/winunits-base/src/typelib.pas svneol=native#text/plain
 packages/winunits-base/src/uxtheme.pp svneol=native#text/plain
 packages/winunits-base/src/uxtheme.pp svneol=native#text/plain
 packages/winunits-base/src/win9xwsmanager.pp svneol=native#text/pascal
 packages/winunits-base/src/win9xwsmanager.pp svneol=native#text/pascal
 packages/winunits-base/src/wininet.pp svneol=native#text/plain
 packages/winunits-base/src/wininet.pp svneol=native#text/plain

File diff suppressed because it is too large
+ 634 - 2178
packages/winunits-base/Makefile


+ 1 - 1
packages/winunits-base/Makefile.fpc

@@ -13,7 +13,7 @@ packages=fcl-registry fcl-base
 units=buildwinutilsbase
 units=buildwinutilsbase
 implicitunits=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver \
 implicitunits=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver \
 	shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp winutils comserv winspool imm imm_dyn nb30 \
 	shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp winutils comserv winspool imm imm_dyn nb30 \
-        win9xwsmanager
+        win9xwsmanager stdole2 typelib
 
 
 examples=examples
 examples=examples
 
 

+ 4 - 0
packages/winunits-base/fpmake.pp

@@ -56,6 +56,8 @@ begin
           AddUnit('multimon');
           AddUnit('multimon');
           AddUnit('htmlhelp');
           AddUnit('htmlhelp');
           AddUnit('winspool');
           AddUnit('winspool');
+		  AddUnit('stdole2');
+		  AddUnit('typelib');
         end;
         end;
     T:=P.Targets.AddImplicitUnit('activex.pp');
     T:=P.Targets.AddImplicitUnit('activex.pp');
     T:=P.Targets.AddImplicitUnit('comconst.pp');
     T:=P.Targets.AddImplicitUnit('comconst.pp');
@@ -80,6 +82,8 @@ begin
     T:=P.Targets.AddImplicitUnit('dwmapi.pp');
     T:=P.Targets.AddImplicitUnit('dwmapi.pp');
     T:=P.Targets.AddImplicitUnit('htmlhelp.pp');
     T:=P.Targets.AddImplicitUnit('htmlhelp.pp');
     T:=P.Targets.AddImplicitUnit('winspool.pp');
     T:=P.Targets.AddImplicitUnit('winspool.pp');
+	T:=P.Targets.AddImplicitUnit('stdole2');
+	T:=P.Targets.AddImplicitUnit('typelib');
     T.Dependencies.AddInclude('tmschema.inc');
     T.Dependencies.AddInclude('tmschema.inc');
     P.ExamplePath.Add('tests/');
     P.ExamplePath.Add('tests/');
     P.Targets.AddExampleProgram('testcom1.pp');
     P.Targets.AddExampleProgram('testcom1.pp');

+ 2 - 1
packages/winunits-base/src/buildwinutilsbase.pp

@@ -24,7 +24,8 @@ uses
     flatsb, winver, mmsystem, comconst, commctrl, comobj, commdlg,
     flatsb, winver, mmsystem, comconst, commctrl, comobj, commdlg,
     ole2, activex, shellapi, shlobj, oleserver,  shfolder, richedit,
     ole2, activex, shellapi, shlobj, oleserver,  shfolder, richedit,
     imagehlp, wininet, uxtheme, dwmapi, multimon, htmlhelp, winutils,
     imagehlp, wininet, uxtheme, dwmapi, multimon, htmlhelp, winutils,
-    comserv, winspool, imm, imm_dyn, nb30, win9xwsmanager;
+    comserv, winspool, imm, imm_dyn, nb30, win9xwsmanager, stdole2, 
+	typelib;
 
 
 implementation
 implementation
 
 

+ 286 - 0
packages/winunits-base/src/stdole2.pas

@@ -0,0 +1,286 @@
+Unit stdole2;
+
+//  Imported on 24/12/2011 13:43:11 from C:\WINDOWS\system32\stdole2.tlb
+//  Modified by Ludo Brands to remove redeclarations
+//  Warning: renamed method 'Reset' in IEnumVARIANT to 'Reset_'
+//  Warning: renamed property 'Type' in IPicture to 'Type_'
+//  Warning: 'pointer' not automatable in Picturedisp.Render
+//  Warning: renamed property 'Type' in Picture to 'Type_'
+
+{$mode delphi}{$H+}
+
+interface
+uses Windows, ActiveX, Classes, OleServer, Variants;
+Const
+  stdoleMajorVersion = 2;
+  stdoleMinorVersion = 0;
+
+  LIBID_stdole : TGUID = '{00020430-0000-0000-C000-000000000046}';
+
+  IID_IUnknown : TGUID = '{00000000-0000-0000-C000-000000000046}';
+  IID_IDispatch : TGUID = '{00020400-0000-0000-C000-000000000046}';
+  IID_IEnumVARIANT : TGUID = '{00020404-0000-0000-C000-000000000046}';
+  IID_IFont : TGUID = '{BEF6E002-A874-101A-8BBA-00AA00300CAB}';
+  IID_Font : TGUID = '{BEF6E003-A874-101A-8BBA-00AA00300CAB}';
+  CLASS_StdFont : TGUID = '{0BE35203-8F91-11CE-9DE3-00AA004BB851}';
+  IID_IPicture : TGUID = '{7BF80980-BF32-101A-8BBB-00AA00300CAB}';
+  IID_Picture : TGUID = '{7BF80981-BF32-101A-8BBB-00AA00300CAB}';
+  CLASS_StdPicture : TGUID = '{0BE35204-8F91-11CE-9DE3-00AA004BB851}';
+  IID_FontEvents : TGUID = '{4EF6100A-AF88-11D0-9846-00C04FC29993}';
+
+//Enums
+Type
+  OLE_TRISTATE =TOleEnum;
+Const
+  Unchecked = $0000000000000000;
+  Checked = $0000000000000001;
+  Gray = $0000000000000002;
+Type
+  LoadPictureConstants =TOleEnum;
+Const
+  Default = $0000000000000000;
+  Monochrome = $0000000000000001;
+  VgaColor = $0000000000000002;
+  Color = $0000000000000004;
+
+//Forward declarations
+Type
+ IEnumVARIANT = interface;
+ IFont = interface;
+ Font = dispinterface;
+ IPicture = interface;
+ Picture = dispinterface;
+ FontEvents = dispinterface;
+
+//records, unions, aliases
+ EXCEPINFO = packed record
+     wCode : Word;
+     wReserved : Word;
+     bstrSource : WideString;
+     bstrDescription : WideString;
+     bstrHelpFile : WideString;
+     dwHelpContext : LongWord;
+     pvReserved : Ppointer;
+     pfnDeferredFillIn : Ppointer;
+     scode : SCODE;
+ end;
+     OLE_COLOR = LongWord;
+     OLE_XPOS_PIXELS = Integer;
+     OLE_YPOS_PIXELS = Integer;
+     OLE_XSIZE_PIXELS = Integer;
+     OLE_YSIZE_PIXELS = Integer;
+     OLE_XPOS_HIMETRIC = Integer;
+     OLE_YPOS_HIMETRIC = Integer;
+     OLE_XSIZE_HIMETRIC = Integer;
+     OLE_YSIZE_HIMETRIC = Integer;
+     OLE_XPOS_CONTAINER = Single;
+     OLE_YPOS_CONTAINER = Single;
+     OLE_XSIZE_CONTAINER = Single;
+     OLE_YSIZE_CONTAINER = Single;
+     OLE_HANDLE = SYSINT;
+     OLE_OPTEXCLUSIVE = WordBool;
+     OLE_CANCELBOOL = WordBool;
+     OLE_ENABLEDEFAULTBOOL = WordBool;
+     FONTNAME = WideString;
+     FONTSIZE = Currency;
+     FONTBOLD = WordBool;
+     FONTITALIC = WordBool;
+     FONTUNDERSCORE = WordBool;
+     FONTSTRIKETHROUGH = WordBool;
+     IFontDisp = Font;
+     IPictureDisp = Picture;
+     IFontEventsDisp = FontEvents;
+
+//interface declarations
+
+// IEnumVARIANT :
+
+ IEnumVARIANT = interface(IUnknown)
+   ['{00020404-0000-0000-C000-000000000046}']
+    // Next :  
+   procedure Next(celt:LongWord;var rgvar:OleVariant;out pceltFetched:LongWord);stdcall;
+    // Skip :  
+   procedure Skip(celt:LongWord);stdcall;
+    // Reset_ :  
+   procedure Reset_;stdcall;
+    // Clone :  
+   procedure Clone(out ppenum:IEnumVARIANT);stdcall;
+  end;
+
+// IFont : Font Object
+
+ IFont = interface(IUnknown)
+   ['{BEF6E002-A874-101A-8BBA-00AA00300CAB}']
+   function Get_Name : WideString; stdcall;
+   procedure Set_Name(const pname:WideString); stdcall;
+   function Get_Size : Currency; stdcall;
+   procedure Set_Size(const psize:Currency); stdcall;
+   function Get_Bold : WordBool; stdcall;
+   procedure Set_Bold(const pbold:WordBool); stdcall;
+   function Get_Italic : WordBool; stdcall;
+   procedure Set_Italic(const pitalic:WordBool); stdcall;
+   function Get_Underline : WordBool; stdcall;
+   procedure Set_Underline(const punderline:WordBool); stdcall;
+   function Get_Strikethrough : WordBool; stdcall;
+   procedure Set_Strikethrough(const pstrikethrough:WordBool); stdcall;
+   function Get_Weight : Smallint; stdcall;
+   procedure Set_Weight(const pweight:Smallint); stdcall;
+   function Get_Charset : Smallint; stdcall;
+   procedure Set_Charset(const pcharset:Smallint); stdcall;
+   function Get_hFont : OLE_HANDLE; stdcall;
+    // Clone :  
+   procedure Clone(out ppfont:IFont);stdcall;
+    // IsEqual :  
+   procedure IsEqual(pfontOther:IFont);stdcall;
+    // SetRatio :  
+   procedure SetRatio(cyLogical:Integer;cyHimetric:Integer);stdcall;
+    // AddRefHfont :  
+   procedure AddRefHfont(hFont:OLE_HANDLE);stdcall;
+    // ReleaseHfont :  
+   procedure ReleaseHfont(hFont:OLE_HANDLE);stdcall;
+    // Name :  
+   property Name:WideString read Get_Name write Set_Name;
+    // Size :  
+   property Size:Currency read Get_Size write Set_Size;
+    // Bold :  
+   property Bold:WordBool read Get_Bold write Set_Bold;
+    // Italic :  
+   property Italic:WordBool read Get_Italic write Set_Italic;
+    // Underline :  
+   property Underline:WordBool read Get_Underline write Set_Underline;
+    // Strikethrough :  
+   property Strikethrough:WordBool read Get_Strikethrough write Set_Strikethrough;
+    // Weight :  
+   property Weight:Smallint read Get_Weight write Set_Weight;
+    // Charset :  
+   property Charset:Smallint read Get_Charset write Set_Charset;
+    // hFont :  
+   property hFont:OLE_HANDLE read Get_hFont ;
+  end;
+
+// Font : 
+
+ Font = dispinterface
+   ['{BEF6E003-A874-101A-8BBA-00AA00300CAB}']
+    // Name :  
+   property Name:WideString  dispid 0;
+    // Size :  
+   property Size:Currency  dispid 2;
+    // Bold :  
+   property Bold:WordBool  dispid 3;
+    // Italic :  
+   property Italic:WordBool  dispid 4;
+    // Underline :  
+   property Underline:WordBool  dispid 5;
+    // Strikethrough :  
+   property Strikethrough:WordBool  dispid 6;
+    // Weight :  
+   property Weight:Smallint  dispid 7;
+    // Charset :  
+   property Charset:Smallint  dispid 8;
+  end;
+
+// IPicture : Picture Object
+
+ IPicture = interface(IUnknown)
+   ['{7BF80980-BF32-101A-8BBB-00AA00300CAB}']
+   function Get_Handle : OLE_HANDLE; stdcall;
+   function Get_hPal : OLE_HANDLE; stdcall;
+   function Get_Type_ : Smallint; stdcall;
+   function Get_Width : OLE_XSIZE_HIMETRIC; stdcall;
+   function Get_Height : OLE_YSIZE_HIMETRIC; stdcall;
+    // Render :  
+   procedure Render(hdc:SYSINT;x:Integer;y:Integer;cx:Integer;cy:Integer;xSrc:OLE_XPOS_HIMETRIC;ySrc:OLE_YPOS_HIMETRIC;cxSrc:OLE_XSIZE_HIMETRIC;cySrc:OLE_YSIZE_HIMETRIC;var prcWBounds:pointer);stdcall;
+   procedure Set_hPal(const phpal:OLE_HANDLE); stdcall;
+   function Get_CurDC : SYSINT; stdcall;
+    // SelectPicture :  
+   procedure SelectPicture(hdcIn:SYSINT;out phdcOut:SYSINT;out phbmpOut:OLE_HANDLE);stdcall;
+   function Get_KeepOriginalFormat : WordBool; stdcall;
+   procedure Set_KeepOriginalFormat(const pfkeep:WordBool); stdcall;
+    // PictureChanged :  
+   procedure PictureChanged;stdcall;
+    // SaveAsFile :  
+   procedure SaveAsFile(var pstm:pointer;fSaveMemCopy:WordBool;out pcbSize:Integer);stdcall;
+   function Get_Attributes : Integer; stdcall;
+    // SetHdc :  
+   procedure SetHdc(hdc:OLE_HANDLE);stdcall;
+    // Handle :  
+   property Handle:OLE_HANDLE read Get_Handle ;
+    // hPal :  
+   property hPal:OLE_HANDLE read Get_hPal write Set_hPal;
+    // Type :  
+   property Type_:Smallint read Get_Type_ ;
+    // Width :  
+   property Width:OLE_XSIZE_HIMETRIC read Get_Width ;
+    // Height :  
+   property Height:OLE_YSIZE_HIMETRIC read Get_Height ;
+    // CurDC :  
+   property CurDC:SYSINT read Get_CurDC ;
+    // KeepOriginalFormat :  
+   property KeepOriginalFormat:WordBool read Get_KeepOriginalFormat write Set_KeepOriginalFormat;
+    // Attributes :  
+   property Attributes:Integer read Get_Attributes ;
+  end;
+
+// Picture : 
+
+ Picture = dispinterface
+   ['{7BF80981-BF32-101A-8BBB-00AA00300CAB}']
+    // Render :  
+   procedure Render(hdc:SYSINT;x:Integer;y:Integer;cx:Integer;cy:Integer;xSrc:OLE_XPOS_HIMETRIC;ySrc:OLE_YPOS_HIMETRIC;cxSrc:OLE_XSIZE_HIMETRIC;cySrc:OLE_YSIZE_HIMETRIC;prcWBounds:{!! pointer !!} OleVariant);dispid 6;
+    // Handle :  
+   property Handle:OLE_HANDLE  dispid 0;
+    // hPal :  
+   property hPal:OLE_HANDLE  dispid 2;
+    // Type :  
+   property Type_:Smallint  dispid 3;
+    // Width :  
+   property Width:OLE_XSIZE_HIMETRIC  dispid 4;
+    // Height :  
+   property Height:OLE_YSIZE_HIMETRIC  dispid 5;
+  end;
+
+// FontEvents : Event interface for the Font object
+
+ FontEvents = dispinterface
+   ['{4EF6100A-AF88-11D0-9846-00C04FC29993}']
+    // FontChanged :  
+   procedure FontChanged(PropertyName:WideString);dispid 9;
+  end;
+
+//CoClasses
+  CoStdFont =class
+    class function Create: Font;
+    class function CreateRemote(const MachineName: string): Font;
+  end;
+  CoStdPicture =class
+    class function Create: Picture;
+    class function CreateRemote(const MachineName: string): Picture;
+  end;
+
+implementation
+
+uses comobj;
+
+class function CoStdFont.Create: Font;
+begin
+  Result := CreateComObject(CLASS_StdFont) as Font;
+end;
+
+class function CoStdFont.CreateRemote(const MachineName: string): Font;
+begin
+  Result := CreateRemoteComObject(MachineName,CLASS_StdFont) as Font;
+end;
+
+class function CoStdPicture.Create: Picture;
+begin
+  Result := CreateComObject(CLASS_StdPicture) as Picture;
+end;
+
+class function CoStdPicture.CreateRemote(const MachineName: string): Picture;
+begin
+  Result := CreateRemoteComObject(MachineName,CLASS_StdPicture) as Picture;
+end;
+
+
+end.

+ 1130 - 0
packages/winunits-base/src/typelib.pas

@@ -0,0 +1,1130 @@
+unit typelib;
+
+{$mode objfpc}{$H+}
+
+{ Typelib import routines.
+
+  Creates freepascal bindings for COM objects stored in .tlb, .dll, .exe or .olb files.
+
+  Copyright (C) 2011 Ludo Brands
+
+  This library is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Library General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or (at your
+  option) any later version with the following modification:
+
+  As a special exception, the copyright holders of this library give you
+  permission to link this library with independent modules to produce an
+  executable, regardless of the license terms of these independent modules,and
+  to copy and distribute the resulting executable under terms of your choice,
+  provided that you also meet, for each linked independent module, the terms
+  and conditions of the license of that module. An independent module is a
+  module which is not derived from or based on this library. If you modify
+  this library, you may extend this exception to your version of the library,
+  but you are not obligated to do so. If you do not wish to do so, delete this
+  exception statement from your version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
+  for more details.
+
+  You should have received a copy of the GNU Library General Public License
+  along with this library; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+}
+
+interface
+
+uses
+  Classes, SysUtils,comobj,activex,windows;
+
+{
+Reads type information from 'FileName' and converts it in a freepascal binding unit. The
+contents of the unit is returned as the function result.
+Returns in 'sUnitName' the unit name with '.pas' extension.
+Appends to 'slDependencies' the filenames of the additional typelibs needed.
+
+By default, the type library is extracted from the first resource of type ITypeLib.
+To load a different type of library resource, append an integer index to 'FileName'.
+
+Example:  C:\WINDOWS\system32\msvbvm60.dll\3
+}
+function ImportTypelib(FileName: WideString;var sUnitName:string;var slDependencies:TStringList):string;
+
+
+Type
+
+  { TTypeLibImporter }
+
+  TTypeLibImporter = Class(TComponent)
+  private
+    FAppendVersionNumber: Boolean;
+    FDependencies: TStringList;
+    FUnitSource: TStringList;
+    FInputFileName: WideString;
+    FOutputFileName: String;
+    FUnitname: string;
+    FUses : TStrings;
+    FHeader : TStrings;
+    FInterface : TStrings;
+    FImplementation : TStrings;
+    procedure CreateCoClasses(const TL: ITypeLib; TICount: Integer);
+    procedure CreateForwards(const TL: ITypeLib; TICount: Integer);
+    procedure CreateInterfaces(const TL: ITypeLib; TICount: Integer);
+    procedure CreateRecordsUnionsAliases(const TL: ITypeLib; TICount: Integer);
+    procedure CreateUnitHeader(const TL: ITypeLib; const LA: lpTLIBATTR);
+    function GetDependencies: TStrings;
+    function GetUnitSource: TStrings;
+    procedure ImportEnums(const TL: ITypeLib; TICount: Integer);
+    procedure ImportGUIDs(const TL: ITypeLib; TICount: Integer);
+    procedure SetOutputFileName(AValue: String);
+    procedure SetUnitName(AValue: string);
+  Protected
+    bIsCustomAutomatable,bIsInterface,bIsAutomatable:boolean;
+    // Construct unit from header, uses, interface,
+    procedure BuildUnit; virtual;
+    // Add to various parts of sources
+    Procedure AddToUses(Const AUnit : String); virtual;
+    Procedure AddToHeader(Const ALine : String; AllowDuplicate : Boolean = False);virtual;
+    Procedure AddToHeader(Const Fmt : String; Args : Array of const; AllowDuplicate : Boolean = False);
+    Procedure AddToInterface(Const ALine : String);virtual;
+    Procedure AddToInterface(Const Fmt : String; Args : Array of const);
+    Procedure AddToImplementation(Const ALine : String);virtual;
+    Procedure AddToImplementation(Const Fmt : String; Args : Array of const);
+    // utility functions
+    function interfacedeclaration(iName, iDoc: string; TI: ITypeInfo; TA: LPTYPEATTR; bIsDispatch: boolean): string;
+    function VarTypeIsAutomatable(ParamType: integer): boolean; virtual;
+    function VarTypeToStr(ParamType: integer): string; virtual;
+    function TypeToString(TI: ITypeInfo; TD: TYPEDESC): string; virtual;
+    function ValidateID(id: string): boolean; virtual;
+    // The actual routine that does the work.
+    Procedure DoImportTypelib;virtual;
+    // For the benefit of descendents;
+    Property UsesClause : TStrings read FUses;
+    Property Header : TStrings read FHeader;
+    Property InterfaceSection : TStrings Read FInterface;
+    Property ImplementationSection : TStrings Read FImplementation;
+  Public
+    Constructor Create(AOwner : TComponent); override;
+    Destructor Destroy; override;
+    Procedure Execute;
+    Property Dependencies : TStrings Read GetDependencies;
+    Property UnitSource : TStrings Read GetUnitSource;
+  Published
+    // Append version number to unit name.
+    Property AppendVersionNumber : Boolean Read FAppendVersionNumber Write FAppendVersionNumber Default True;
+    // File to read typelib from.
+    Property InputFileName : WideString Read FInputFileName Write FInputFileName;
+    // If set, unit source will be written to this file.
+    Property OutputFileName : String Read FOutputFileName Write SetOutputFileName;
+    // Set automatically by OutputFileName or by Execute
+    Property UnitName : string Read FUnitname Write SetUnitName;
+  end;
+
+
+implementation
+
+Resourcestring
+  SErrInvalidUnitName = 'Invalid unit name : %s';
+
+function ImportTypelib(FileName: WideString;var sUnitName:string;var slDependencies:TStringList):string;
+var i:integer;
+begin
+  With TTypeLibImporter.Create(Nil) do
+    try
+      InputFileName:=FileName;
+      Execute;
+      Result:=UnitSource.Text;
+      sUnitname:=UnitName+'.pas';
+      if Assigned(slDependencies) then
+        begin  //add new dependencies
+        for i:=0 to Dependencies.Count-1 do
+          if slDependencies.IndexOf(Dependencies[i])=-1 then
+            slDependencies.Add(Dependencies[i]);
+        end;
+    finally
+      Free;
+    end;
+end;
+
+function TTypeLibImporter.VarTypeIsAutomatable(ParamType:integer): boolean;
+
+begin
+result:=ParamType in [vt_i1,vt_ui1,vt_i2,vt_ui2,vt_i4,vt_ui4,vt_uint,
+            vt_i8,VT_UI8,vt_bool,vt_r4,vt_r8,vt_cy,vt_date,
+            VT_BSTR,VT_VARIANT,VT_DISPATCH,VT_UNKNOWN,vt_hresult,VT_INT];
+end;
+
+function TTypeLibImporter.VarTypeToStr(ParamType:integer): string;
+
+begin
+  case ParamType of
+    vt_empty : Result := 'Empty';
+    vt_null : Result := 'Null';
+    vt_i2 : Result := 'Smallint';
+    vt_i4 : Result := 'Integer';
+    vt_r4 : Result := 'Single';
+    vt_r8 : Result := 'Double';
+    vt_cy : Result := 'Currency';
+    vt_date : Result := 'TDateTime';
+    vt_bstr : Result := 'WideString';
+    vt_dispatch  : Result := 'IDispatch';
+    vt_error : Result := 'SCODE';
+    vt_bool : Result := 'WordBool';
+    vt_variant : Result := 'OleVariant';
+    vt_unknown : Result := 'IUnknown';
+    vt_i1  : Result := 'ShortInt';
+    vt_ui1 : Result := 'Byte';
+    vt_ui2 : Result := 'Word';
+    vt_ui4  : Result := 'LongWord';
+    vt_i8 : Result := 'Int64';
+    VT_UI8: Result := 'QWord';
+    vt_clsid : Result := 'TGUID';
+    vt_void : Result := 'pointer';
+    vt_ptr : Result := 'Pointer';
+    vt_uint : Result := 'UInt';
+    vt_userdefined : Result := 'User defined';
+    vt_hresult : Result := 'HResult';
+    VT_INT:Result:='SYSINT';
+    VT_SAFEARRAY:Result:='PSafeArray';
+  else
+    Result := 'Unknown (' + IntToStr(ParamType) + ')';
+  end;
+end;
+
+function TTypeLibImporter.ValidateID(id:string):boolean;
+
+const
+  RESERVEDCNT=111;
+  RESERVED:array[1..RESERVEDCNT] of string=
+  ('absolute','and','array','asm','begin','break','case','const',
+  'constructor','continue','destructor','div','do','downto','else','end',
+  'file','for','function','goto','if','implementation','in','inherited',
+  'inline','interface','label','mod','nil','not','object','of',
+  'on','operator','or','packed','procedure','program','record','reintroduce',
+  'repeat','self','set','shl','shr','string','then','to',
+  'type','unit','until','uses','var','while','with','xor',
+  'as','class','except','exports','finalization','finally','initialization',
+  'is','library','on','property','raise','threadvar','try',
+  'dispose','exit','false','new','true',
+  'abs','arctan','boolean','char','cos','dispose','eof','eoln',
+  'exp','false','input','integer','ln','maxint','new','odd',
+  'ord','output','pack','page','pred','read','readln','real',
+  'reset','rewrite','round','sin','sqr','sqrt','succ','text',
+  'true','trunc','write','writeln');
+
+var
+  sl:string;
+  i:integer;
+
+begin
+  sl:=lowercase(id);
+  result:=true;
+  for i:=1 to RESERVEDCNT do
+    if sl= RESERVED[i] then
+      begin
+      result:=false;
+      break;
+      end;
+end;
+
+
+function TTypeLibImporter.TypeToString(TI:ITypeInfo; TD:TYPEDESC):string;
+
+var
+  TIref: ITypeInfo;
+  TARef:LPTYPEATTR;
+  TLRef: ITypeLib;
+  LARef: lpTLIBATTR;
+  BstrName : WideString;
+  il:LongWord;
+  i,idims:integer;
+  sl,sRefSrc,sKey:string;
+  Handle:HKEY;
+  bWasPointer:boolean;
+begin
+  result:='';
+  bIsCustomAutomatable:=false;
+  bIsInterface:=false;
+  if (TD.vt=vt_userdefined) or ((TD.vt=VT_PTR) and (TD.lptdesc^.vt=vt_userdefined)) then
+    begin
+    // interface references are dealt with now because they are pointers in fpc.
+    // Recursive algorithm makes it difficult to remove a single preceding 'P' from the result.
+    bWasPointer:=(TD.vt=VT_PTR);
+    if bWasPointer then
+      TD:=TD.lptdesc^;
+    OleCheck(TI.GetRefTypeInfo(TD.hreftype,TIref));
+    OleCheck(TIRef.GetDocumentation(DISPID_UNKNOWN, @BstrName, nil, nil, nil));
+    result:=BstrName;
+    OleCheck(TIRef.GetTypeAttr(TARef));
+    bIsCustomAutomatable:=TARef^.typekind in [TKIND_DISPATCH,TKIND_INTERFACE,TKIND_ENUM];
+    if TARef^.typekind=TKIND_ALIAS then
+      begin
+      TypeToString(TIRef,TARef^.tdescAlias); //not interested in result, only bIsCustomAutomatable and bIsInterface
+      bIsCustomAutomatable:=bIsAutomatable;
+      end
+    else
+      bIsInterface:=TARef^.typekind in [TKIND_DISPATCH,TKIND_INTERFACE] ;
+    if bWasPointer and not bIsInterface then  // interfaces are pointers to interface in fpc
+      result:='P'+result;
+    OleCheck(TIRef.GetContainingTypeLib(TLRef,il));
+    OleCheck(TLRef.GetDocumentation(-1, @BstrName, nil, nil, nil));
+    OleCheck(TLRef.GetLibAttr(LARef));
+    if FAppendVersionNumber then
+      sl:=format('%s_%d_%d_TLB',[BstrName,LARef^.wMajorVerNum,LARef^.wMinorVerNum])
+    else
+      sl:=format('%s_TLB',[BstrName]);
+    if (LowerCase(BstrName)='stdole') then // don't include, uses pre-defined stdole2.pas if V2
+      begin
+      if (LARef^.wMajorVerNum=2) and (FUses.IndexOf('stdole2')=-1) then
+        begin
+        AddToHeader('// Dependency: stdole v2 (stdole2.pas)');
+        FUses.Add('stdole2');
+        end;
+      end
+    else if (LowerCase(sl)<>LowerCase(UnitName)) and (FUses.IndexOf(sl)=-1) then
+      begin  // add dependency
+      // find source in registry key HKEY_CLASSES_ROOT\TypeLib\GUID\version\0\win32
+      il:=MAX_PATH;
+      SetLength(sRefSrc,il);
+      sKey:=format('\TypeLib\%s\%d.%d\0\win32',[GUIDToString(LARef^.GUID),LARef^.wMajorVerNum,LARef^.wMinorVerNum]);
+      if (RegOpenKeyEx(HKEY_CLASSES_ROOT,pchar(sKey),0,KEY_READ,Handle) = ERROR_SUCCESS) then
+        begin
+        if RegQueryValue(Handle,nil,@sRefSrc[1],@il) = ERROR_SUCCESS then
+          begin
+          SetLength(sRefSrc,il-1);  // includes null terminator
+          if not FDependencies.Find(sRefSrc,i) then
+            FDependencies.Add(sRefSrc);
+          end
+        else
+          sRefSrc:=GUIDToString(LARef^.GUID);
+        RegCloseKey(Handle);
+        end;
+      AddToHeader('// Dependency: %s v%d.%d (%s)',[BstrName,LARef^.wMajorVerNum,LARef^.wMinorVerNum,sRefSrc]);
+      FUses.Add(sl);
+      TLRef.ReleaseTLibAttr(LARef);
+      end;
+    TIRef.ReleaseTypeAttr(TARef);
+    end
+  else if TD.vt=VT_PTR then //pointer type
+    begin
+    TD:=TD.lptdesc^;
+    result:='P'+TypeToString(TI,TD);
+    bIsAutomatable:=(VarTypeIsAutomatable(TD.vt) and (TD.vt<>VT_VARIANT)) or bIsCustomAutomatable;
+    exit;
+    end
+  else if TD.vt=VT_CARRAY then //C type array
+    begin
+    // get array element type
+    sl:=TypeToString(TI,TD.lpadesc^.tdescElem);
+    // get dimensions
+    idims:=TD.lpadesc^.cDims;
+    result:='array[';
+    // get boundaries for every dimension
+    for i:=0 to idims-1 do
+      result:=result+IntToStr(TD.lpadesc^.rgbounds[i].lLbound)+'..'+IntToStr(TD.lpadesc^.rgbounds[i].cElements - TD.lpadesc^.rgbounds[i].lLbound -1)+',';
+    result[length(result)]:=']';
+    result:=result + ' of '+sl;
+    end
+  else
+    result:=VarTypeToStr(TD.vt);
+  bIsAutomatable:=VarTypeIsAutomatable(TD.vt) or bIsCustomAutomatable;
+end;
+
+function TTypeLibImporter.interfacedeclaration(iName,iDoc:string;TI:ITypeInfo;TA:LPTYPEATTR;bIsDispatch:boolean):string;
+
+type
+  TPropertyDef=record
+    idispid:integer;
+    bput,bget:boolean;
+    iptype,igtype:integer;
+    name,
+    sptype,          // only used if iptype=igtype
+    sorgname,
+    sdoc,
+    sParam,
+    sDefault:string;
+  end;
+
+var
+  RTIT: HREFTYPE;
+  TIref: ITypeInfo;
+  BstrName,BstrNameRef,BstrDocString : WideString;
+  s,sl,sPropIntfc,sPropDispIntfc,sType,sConv,sFunc,sVarName,sMethodName,sPropParam,sPropParam2:string;
+  i,j,k:integer;
+  FD: lpFUNCDESC;
+  BL : array[0..99] of TBstr;
+  cnt:LongWord;
+  TD: TYPEDESC;
+  bPropHasParam,bIsFunction:boolean;
+  VD: lpVARDESC;
+  aPropertyDefs:array of TPropertyDef;
+  Propertycnt,iType:integer;
+
+  function findProperty(ireqdispid:integer):integer;
+  var i:integer;
+  begin
+    for i:=0 to Propertycnt-1 do
+      if aPropertyDefs[i].idispid=ireqdispid then
+        begin
+        result:=i;
+        exit;
+        end;
+    result:=Propertycnt;
+    Propertycnt:=Propertycnt+1;
+    with aPropertyDefs[result] do
+      begin
+      idispid:=ireqdispid;
+      bput:=false;
+      bget:=false;
+      name:='';
+      iptype:=vt_empty;
+      igtype:=vt_empty;
+      sptype:='';
+      sorgname:='';
+      sdoc:='';
+      sParam:='';
+      sDefault:='';
+      end;
+  end;
+
+begin
+  Propertycnt:=0;
+  SetLength(aPropertyDefs,TA^.cFuncs+TA^.cVars);   // worst case, all functions getters or all setters
+  result:='TA^.cFuncs';
+  if not bIsDispatch then
+    begin
+    // find base class
+    if TA^.cImplTypes>0 then
+      begin
+      OleCheck(TI.GetRefTypeOfImplType(0,RTIT));
+      OleCheck(TI.GetRefTypeInfo(RTIT,TIref));
+      OleCheck(TIRef.GetDocumentation(DISPID_UNKNOWN, @BstrNameRef, nil, nil, nil));
+      s:=format(#13#10'// %s : %s'#13#10#13#10' %s = interface(%s)'#13#10,[iname,iDoc,iname,BstrNameRef]);
+      end
+    else // no base class
+      begin
+      s:=format(#13#10'// %s : %s'#13#10#13#10' %s = interface'#13#10,[iname,iDoc,iname]);
+      end;
+    end
+  else
+    if (TA^.wTypeFlags and TYPEFLAG_FDUAL)=TYPEFLAG_FDUAL then
+      s:=format(#13#10'// %s : %s'#13#10#13#10' %sDisp = dispinterface'#13#10,[iname,iDoc,iname])
+    else
+      s:=format(#13#10'// %s : %s'#13#10#13#10' %s = dispinterface'#13#10,[iname,iDoc,iname]);
+  sPropIntfc:='';
+  sPropDispIntfc:='';
+  s:=s+format('   [''%s'']'#13#10,[GUIDToString(TA^.GUID)]);
+  for j:=0 to TA^.cFuncs-1 do
+    begin
+    OleCheck(TI.GetFuncDesc(j,FD));
+    OleCheck(TI.GetNames(FD^.memid,@BL,length(BL),cnt));
+    // skip IUnknown and IDispatch methods
+    sl:=lowercase(BL[0]);
+    if (sl='queryinterface') or (sl='addref') or (sl='release') then  //IUnknown
+      continue;
+    if bIsDispatch and
+      ((sl='gettypeinfocount') or (sl='gettypeinfo') or (sl='getidsofnames') or (sl='invoke')) then  //IDispatch
+      continue;
+    // get return type
+    if bIsDispatch and ((FD^.invkind=INVOKE_PROPERTYGET) or (FD^.invkind=INVOKE_FUNC)) then
+      begin
+      sType:=TypeToString(TI,FD^.elemdescFunc.tdesc);
+      iType:=FD^.elemdescFunc.tdesc.vt;
+      end
+    else
+      if FD^.cParams>0 then
+        begin
+        sType:=TypeToString(TI,FD^.lprgelemdescParam[FD^.cParams-1].tdesc);
+        iType:=FD^.lprgelemdescParam[FD^.cParams-1].tdesc.vt;
+        if ((FD^.lprgelemdescParam[FD^.cParams-1].paramdesc.wParamFlags and (PARAMFLAG_FRETVAL or PARAMFLAG_FOUT)) <>0) then
+          begin
+          delete(sType,1,1); //out parameters are always defined as pointer
+          if assigned(FD^.lprgelemdescParam[FD^.cParams-1].tdesc.lptdesc) then
+            iType:=FD^.lprgelemdescParam[FD^.cParams-1].tdesc.lptdesc^.vt;
+          end;
+        end;
+    //get calling convention
+    if FD^.callconv=CC_STDCALL then
+      begin
+      if lowercase(BstrNameRef)='iunknown' then
+        sConv:='stdcall'
+      else
+        sConv:='safecall';
+      end
+    else
+      sConv:='cdecl';
+    // get info
+    OleCheck(TI.GetDocumentation(FD^.memid, @BstrName, @BstrDocString, nil, nil));
+    case FD^.invkind of
+      // build function/procedure
+      INVOKE_FUNC :
+        begin
+        if ValidateID(BstrName) then
+          sMethodName:=BstrName
+        else
+          begin
+          sMethodName:=BstrName+'_';
+          AddToHeader('//  Warning: renamed method ''%s'' in %s to ''%s''',[BstrName,iname,sMethodName],True);
+          end;
+        bIsFunction:=(bIsDispatch and (FD^.elemdescFunc.tdesc.vt<>VT_VOID)) or
+          (not bIsDispatch and (FD^.cParams>0) and ((FD^.lprgelemdescParam[FD^.cParams-1].paramdesc.wParamFlags and PARAMFLAG_FRETVAL ) <>0));
+        if bIsFunction then
+          sFunc:=format('    // %s : %s '#13#10'   function %s(',[sMethodName,BstrDocString,sMethodName])
+        else
+          sFunc:=format('    // %s : %s '#13#10'   procedure %s(',[sMethodName,BstrDocString,sMethodName]);
+        if bIsFunction and bIsDispatch and not bIsAutomatable then
+          begin
+          AddToHeader('//  Warning: ''%s'' not automatable in %sdisp.%s',[stype,iname,BstrName],True);
+          sType:='{!! '+sType+' !!} OleVariant';
+          end;
+        // parameters
+        for k:=0 to FD^.cParams-1 do
+          begin
+          if (FD^.lprgelemdescParam[k].paramdesc.wParamFlags and PARAMFLAG_FRETVAL ) <>0 then  //return type
+            continue;
+          sl:=TypeToString(TI,FD^.lprgelemdescParam[k].tdesc);
+          if sMethodName='Clone' then
+            sl:=sl;
+          if (FD^.lprgelemdescParam[k].tdesc.vt=VT_PTR) and                                        // by ref
+            not((FD^.lprgelemdescParam[k].tdesc.lptdesc^.vt=VT_USERDEFINED) and bIsInterface) then // but not pointer to interface
+             delete(sl,1,1);
+          if bIsDispatch and not bIsAutomatable then
+            begin
+            AddToHeader('//  Warning: ''%s'' not automatable in %sdisp.%s',[sl,iname,sMethodName],True);
+            sl:='{!! '+sl+' !!} OleVariant';
+            end;
+          if (FD^.lprgelemdescParam[k].tdesc.vt=VT_PTR) and                                          // by ref
+              not((FD^.lprgelemdescParam[k].tdesc.lptdesc^.vt=VT_USERDEFINED) and bIsInterface) then // but not pointer to interface
+            case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and (PARAMFLAG_FIN or PARAMFLAG_FOUT) of
+            PARAMFLAG_FIN or PARAMFLAG_FOUT:sFunc:=sFunc+'var ';
+            PARAMFLAG_FOUT:sFunc:=sFunc+'out ';
+            PARAMFLAG_FIN:sFunc:=sFunc+'var '; //constref in safecall? TBD
+            end;
+          if ValidateID(BL[k+1]) then
+            sVarName:=BL[k+1]
+          else
+            begin
+            sVarName:=BL[k+1]+'_';
+            AddToHeader('//  Warning: renamed parameter ''%s'' in %s.%s to ''%s'''#13#10,[BL[k+1],iname,sMethodName,sVarName],True);
+            end;
+          sFunc:=sFunc+format('%s:%s;',[sVarName,sl]);
+          end;
+        // finish interface and dispinterface
+        if sFunc[length(sFunc)]=';' then
+          sFunc[length(sFunc)]:=')'
+        else  // no params
+          delete(sFunc,length(sFunc),1);
+        if bIsFunction then
+          sFunc:=sFunc+format(':%s',[sType]);
+        if bIsDispatch then
+          s:=s+sFunc+format(';dispid %d;'#13#10,[FD^.memid])
+        else
+          s:=s+sFunc+format(';%s;'#13#10,[sConv]);
+        end;
+      INVOKE_PROPERTYGET,INVOKE_PROPERTYPUT,INVOKE_PROPERTYPUTREF :
+        // build properties. Use separate string to group properties at end of interface declaration.
+        begin
+        if ValidateID(BstrName) then
+          sMethodName:=BstrName
+        else
+          begin
+          sMethodName:=BstrName+'_';
+          AddToHeader('//  Warning: renamed property ''%s'' in %s to ''%s''',[BstrName,iname,sMethodName]);
+          end;
+        bPropHasParam:=(((FD^.invkind=INVOKE_PROPERTYGET) and (FD^.cParams>0)) or (FD^.cParams>1))
+            and ((FD^.lprgelemdescParam[0].paramdesc.wParamFlags and PARAMFLAG_FIN) = PARAMFLAG_FIN) ;
+        if (FD^.memid=0) and  bPropHasParam then sl:=' default;' else sl:='';
+        sPropParam:='';
+        sPropParam2:='';
+        if bPropHasParam then
+          begin
+          sPropParam:=BL[1]+':'+TypeToString(TI,FD^.lprgelemdescParam[0].tdesc);
+          end;
+        if bIsDispatch then
+          begin
+          if (TD.vt<>VT_VOID) and not bIsAutomatable then
+            begin
+            AddToHeader('//  Warning: ''%s'' not automatable in %s.%s',[stype,iname,BstrName]);
+            sType:='{!! '+sType+' !!} OleVariant';
+            end;
+          if bPropHasParam then
+            sPropParam:='['+sPropParam+']';
+          i:=pos(format('dispid %d;',[FD^.memid]),sPropDispIntfc);
+          if i<=0 then
+            begin
+            if FD^.invkind=INVOKE_PROPERTYGET then
+              sType:=sType+' readonly '
+            else
+              sType:=sType+' writeonly';
+            sPropDispIntfc:=sPropDispIntfc+format('    // %s : %s '#13#10'   property %s%s:%s dispid %d;%s'#13#10,
+              [BstrName,BstrDocString,sMethodName,sPropParam,sType,FD^.memid,sl]);
+            end
+          else //remove readonly or writeonly
+            delete(sPropDispIntfc,i-11,10);   //10= length(' readonly ')
+          end
+        else
+          begin
+          //getters/setters for interface, insert in interface as they come,
+          //store in aPropertyDefs to create properties at the end
+          if bPropHasParam then
+            begin
+            sPropParam2:='('+sPropParam+')';
+            sPropParam:='['+sPropParam+']';
+            end;
+          if FD^.invkind=INVOKE_PROPERTYGET then
+            begin
+            s:=s+format('   function Get_%s%s : %s; %s;'#13#10,[sMethodName,sPropParam2,sType,sConv]);
+            with aPropertyDefs[findProperty(FD^.memid)] do
+              begin
+              bget:=true;
+              name:=sMethodName;
+              igtype:=itype;
+              sptype:=sType;
+              sorgname:=BstrName;
+              sdoc:=BstrDocString;
+              sParam:=sPropParam;
+              sDefault:=sl;
+              end;
+            end
+          else
+            begin
+            if ValidateID(BL[1]) then
+              sVarName:=BL[1]
+            else
+              begin
+              sVarName:=BL[1]+'_';
+              AddToHeader('//  Warning: renamed parameter ''%s'' in %s.Set_%s to ''%s''',[BL[1],iname,sMethodName,sVarName]);
+              end;
+            s:=s+format('   procedure Set_%s(const %s:%s); %s;'#13#10,[sMethodName,sVarName,sType,sConv]);
+            with aPropertyDefs[findProperty(FD^.memid)] do
+              begin
+              bput:=true;
+              name:=sMethodName;
+              iptype:=itype;
+              sptype:=sType;
+              sorgname:=BstrName;
+              sdoc:=BstrDocString;
+              sParam:=sPropParam;
+              sDefault:=sl;
+              end;
+            end;
+          end;
+        end;
+    end;
+    TI.ReleaseFuncDesc(FD);
+    end;
+  for j:=0 to TA^.cVars-1 do
+    begin  //read-write properties only
+    if bIsDispatch then
+      begin
+      TI.GetVarDesc(j,VD);
+      if assigned(VD) then
+        begin
+        TI.GetDocumentation(VD^.memId,@BstrName, @BstrDocString, nil, nil);
+        if ValidateID(BstrName) then
+          sMethodName:=BstrName
+        else
+          begin
+          sMethodName:=BstrName+'_';
+          AddToHeader('//  Warning: renamed property ''%s'' in %s to ''%s'''#13#10,[BstrName,iname,sMethodName]);
+          end;
+        sType:=TypeToString(TI,VD^.ElemdescVar.tdesc);
+        sPropDispIntfc:=sPropDispIntfc+format('    // %s : %s '#13#10'   property %s:%s  dispid %d;'#13#10,
+          [BstrName,BstrDocString,sMethodName,sType,VD^.memId]);
+        end;
+      end;
+    end;
+  if bIsDispatch then
+    result:=s + sPropDispIntfc +'  end;'#13#10
+  else
+    begin
+    // add interface properties
+    for i:=0 to Propertycnt-1 do
+      with aPropertyDefs[i] do
+      if (iptype=igtype) or not bget or not bput then
+        begin
+        s:=s+format('    // %s : %s '#13#10'   property %s%s:%s',[sorgname,sdoc,name,sParam,sptype]);
+        if bget then
+          s:=s+format(' read Get_%s',[name]);
+        if bput then
+          s:=s+format(' write Set_%s',[name]);
+        s:=s+format(';%s'#13#10,[sDefault]);
+        end;
+    result:=s+'  end;'#13#10;
+    end;
+end;
+
+function TTypeLibImporter.GetDependencies: TStrings;
+begin
+  Result:=FDependencies;
+end;
+
+function TTypeLibImporter.GetUnitSource: TStrings;
+begin
+  Result:=FUnitSource;
+end;
+
+Procedure TTypeLibImporter.ImportGUIDs(Const TL : ITypeLib; TICount : Integer);
+
+Var
+  i : integer;
+  BstrName, BstrDocString, BstrHelpFile : WideString;
+  dwHelpContext: DWORD;
+  TI:ITypeInfo;
+  TA:LPTYPEATTR;
+  TIT: TYPEKIND;
+
+begin
+  //GUIDs
+  for i:=0 to TIcount-1 do
+    begin
+    OleCheck(TL.GetTypeInfoType(i, TIT));
+    OleCheck(TL.GetTypeInfo(i, TI));
+    OleCheck(TL.GetDocumentation(i, @BstrName, @BstrDocString, @dwHelpContext, @BstrHelpFile));
+    OleCheck(TI.GetTypeAttr(TA));
+    case TIT of
+      TKIND_DISPATCH,TKIND_INTERFACE:
+        begin
+        AddToInterface('  IID_%s : TGUID = ''%s'';',[BstrName,GUIDToString(TA^.GUID)]);
+        end;
+      TKIND_COCLASS:
+        begin
+        AddToInterface('  CLASS_%s : TGUID = ''%s'';',[BstrName,GUIDToString(TA^.GUID)]);
+        end;
+      end;
+    TI.ReleaseTypeAttr(TA);
+    end;
+end;
+
+Procedure TTypeLibImporter.ImportEnums(Const TL : ITypeLib; TICount : Integer);
+
+Var
+  i,j : integer;
+  sl : string;
+  BstrName, BstrDocString, BstrHelpFile : WideString;
+  dwHelpContext: DWORD;
+  TI:ITypeInfo;
+  TA:LPTYPEATTR;
+  TIT: TYPEKIND;
+  bDuplicate:boolean;
+  VD: lpVARDESC;
+
+begin
+  //enums
+  AddToInterface('');
+  AddToInterface('//Enums');
+  AddToInterface('');
+  for i:=0 to TIcount-1 do
+    begin
+    OleCheck(TL.GetTypeInfoType(i, TIT));
+    OleCheck(TL.GetTypeInfo(i, TI));
+    OleCheck(TL.GetDocumentation(i, @BstrName, @BstrDocString, @dwHelpContext, @BstrHelpFile));
+    OleCheck(TI.GetTypeAttr(TA));
+    if TIT=TKIND_ENUM then
+      begin
+      bDuplicate:=false;
+      sl:=BstrName;
+      if (InterfaceSection.IndexOf(Format('  %s =TOleEnum;',[sl]))<>-1) then  // duplicate enums fe. AXVCL.dll 1.0
+        begin
+        sl:=sl+IntToStr(i); // index is unique in this typelib
+        AddToHeader('//  Warning: duplicate enum ''%s''. Renamed to ''%s''. consts appended with %d',[BstrName,sl,i]);
+        bDuplicate:=true;
+        end;
+      AddToInterface('Type');
+      AddToInterface('  %s =TOleEnum;',[sl]);
+      AddToInterface('Const');
+      for j:=0 to TA^.cVars-1 do
+        begin
+        TI.GetVarDesc(j,VD);
+        if assigned(VD) then
+          begin
+          TI.GetDocumentation(VD^.memId,@BstrName, nil, nil, nil);
+          sl:=BstrName;
+          if bDuplicate then
+            sl:=sl+IntToStr(i);
+          if assigned(VD^.lpvarValue) then
+            AddToInterface('  %s = $%s;',[sl,IntToHex(PtrInt(VD^.lpvarValue^),16)]);
+          end;
+        end;
+      end;
+    TI.ReleaseTypeAttr(TA);
+    end;
+end;
+
+Procedure TTypeLibImporter.CreateForwards(Const TL : ITypeLib; TICount : Integer);
+
+Var
+  i : integer;
+  BstrName, BstrDocString, BstrHelpFile : WideString;
+  dwHelpContext: DWORD;
+  TI:ITypeInfo;
+  TA:LPTYPEATTR;
+  TIT: TYPEKIND;
+
+begin
+  // Forward declarations
+  AddToInterface('//Forward declarations');
+  AddToInterface('');
+  AddToInterface('Type');
+  for i:=0 to TIcount-1 do
+    begin
+    OleCheck(TL.GetTypeInfoType(i, TIT));
+    OleCheck(TL.GetTypeInfo(i, TI));
+    OleCheck(TL.GetDocumentation(i, @BstrName, @BstrDocString, @dwHelpContext, @BstrHelpFile));
+    OleCheck(TI.GetTypeAttr(TA));
+    if (TIT=TKIND_DISPATCH) then
+      begin
+      if (TA^.wTypeFlags and TYPEFLAG_FDUAL)=TYPEFLAG_FDUAL then
+        begin
+        AddToInterface(' %s = interface;',[BstrName]);
+        AddToInterFace(' %sDisp = dispinterface;',[BstrName]);
+        end
+      else
+        AddToInterface(' %s = dispinterface;',[BstrName]);
+      end
+    else if (TIT=TKIND_INTERFACE) then
+      AddToInterface(' %s = interface;',[BstrName]);
+    TI.ReleaseTypeAttr(TA);
+    end;
+end;
+
+Procedure TTypeLibImporter.CreateRecordsUnionsAliases(Const TL : ITypeLib; TICount : Integer);
+
+Var
+  i,j : integer;
+  BstrName, BstrDocString, BstrHelpFile : WideString;
+  dwHelpContext: DWORD;
+  TI:ITypeInfo;
+  TA:LPTYPEATTR;
+  TIT: TYPEKIND;
+  VD: lpVARDESC;
+
+begin
+  //records, unions aliases
+  AddToInterface('');
+  AddToInterface('//records, unions, aliases');
+  AddToInterface('');
+
+  for i:=0 to TIcount-1 do
+    begin
+    OleCheck(TL.GetTypeInfoType(i, TIT));
+    //s:=s+format('type %d'#13#10,[ord(TIT)]);
+    OleCheck(TL.GetTypeInfo(i, TI));
+    OleCheck(TL.GetDocumentation(i, @BstrName, @BstrDocString, @dwHelpContext, @BstrHelpFile));
+    OleCheck(TI.GetTypeAttr(TA));
+    case TIT of
+      TKIND_RECORD:
+        begin
+        AddToInterface(' P%s = ^%s;',[BstrName,BstrName]);
+        AddToInterface(' %s = packed record',[BstrName]);
+        for j:=0 to TA^.cVars-1 do
+          begin
+          TI.GetVarDesc(j,VD);
+          TI.GetDocumentation(VD^.memId,@BstrName, @BstrDocString, @dwHelpContext, @BstrHelpFile);
+          AddToInterface('     %s : %s;',[BstrName,TypeToString(TI, VD^.ElemdescVar.tdesc)]);
+          end;
+        AddToInterface(' end;');
+        end;
+      TKIND_ALIAS:
+        begin
+        AddToInterface('     %s = %s;',[BstrName,TypeToString(TI, TA^.tdescAlias)]);
+        end;
+      TKIND_UNION:
+        begin
+        end;
+      end;
+    TI.ReleaseTypeAttr(TA);
+    end;
+end;
+
+Procedure TTypeLibImporter.CreateInterfaces(Const TL : ITypeLib; TICount : Integer);
+
+Var
+  i : integer;
+  BstrName, BstrDocString, BstrHelpFile : WideString;
+  dwHelpContext : DWORD;
+  TI,TIref : ITypeInfo;
+  TA,TAref : LPTYPEATTR;
+  TIT : TYPEKIND;
+  RTIT : HREFTYPE;
+
+begin
+  // interface declarations
+  AddToInterface('//interface declarations');
+  for i:=0 to TIcount-1 do
+    begin
+    OleCheck(TL.GetTypeInfoType(i, TIT));
+    OleCheck(TL.GetTypeInfo(i, TI));
+    OleCheck(TL.GetDocumentation(i, @BstrName, @BstrDocString, @dwHelpContext, @BstrHelpFile));
+    if (TIT=TKIND_DISPATCH) or (TIT=TKIND_INTERFACE) then
+      begin
+      OleCheck(TI.GetTypeAttr(TA));
+      if (TIT=TKIND_DISPATCH) then
+        begin
+        // get also TKIND_INTERFACE if dual interface
+        if (TA^.wTypeFlags and TYPEFLAG_FDUAL)=TYPEFLAG_FDUAL then
+          begin
+          OleCheck(TI.GetRefTypeOfImplType(-1,RTIT));
+          OleCheck(TI.GetRefTypeInfo(RTIT,TIref));
+          OleCheck(TIref.GetTypeAttr(TAref));
+          AddToInterface(interfacedeclaration(BstrName,BstrDocString,TIref,TAref,false));
+          TIref.ReleaseTypeAttr(TAref);
+          end;
+        AddToInterface(interfacedeclaration(BstrName,BstrDocString,TI,TA,true));
+        end
+      else
+        AddToInterface(interfacedeclaration(BstrName,BstrDocString,TI,TA,false));
+      TI.ReleaseTypeAttr(TA);
+      end;
+    end;
+end;
+
+Procedure TTypeLibImporter.CreateCoClasses(Const TL : ITypeLib; TICount : Integer);
+
+Var
+  i : integer;
+  BstrName, BstrDocString, BstrHelpFile, BstrNameRef : WideString;
+  dwHelpContext : DWORD;
+  TI,TIref : ITypeInfo;
+  TA : LPTYPEATTR;
+  TIT : TYPEKIND;
+  RTIT : HREFTYPE;
+
+begin
+  //CoClasses
+  AddToInterface('//CoClasses');
+  AddToImplementation('implementation');
+  AddToImplementation('');
+  AddToImplementation('uses comobj;');
+  AddToImplementation('');
+  for i:=0 to TIcount-1 do
+    begin
+    OleCheck(TL.GetTypeInfoType(i, TIT));
+    if TIT =TKIND_COCLASS then
+      begin
+      OleCheck(TL.GetTypeInfo(i, TI));
+      OleCheck(TL.GetDocumentation(i, @BstrName, @BstrDocString, @dwHelpContext, @BstrHelpFile));
+      OleCheck(TI.GetTypeAttr(TA));
+      OleCheck(TI.GetRefTypeOfImplType(0,RTIT));
+      OleCheck(TI.GetRefTypeInfo(RTIT,TIref));
+      OleCheck(TIRef.GetDocumentation(DISPID_UNKNOWN, @BstrNameRef, nil, nil, nil));
+      AddToInterFace('  Co%s = Class',[BstrName]);
+      AddToInterface('    Class Function Create: %s;',[BstrNameRef]);
+      AddToInterFace('    Class Function CreateRemote(const MachineName: string): %s;',[BstrNameRef]);
+      AddToInterFace('  end;');
+      AddToInterFace('');
+      AddToImplementation('Class Function Co%s.Create: %s;',[BstrName,BstrNameRef]);
+      AddToImplementation('begin');
+      AddToImplementation('  Result := CreateComObject(CLASS_%s) as %s;',[BstrName,BstrNameRef]);
+      AddToImplementation('end;');
+      AddToImplementation('');
+      AddToImplementation('Class Function Co%s.CreateRemote(const MachineName: string): %s;',[BstrName,BstrNameRef]);
+      AddToImplementation('begin');
+      AddToImplementation('  Result := CreateRemoteComObject(MachineName,CLASS_%s) as %s;',[BstrName,BstrNameRef]);
+      AddToImplementation('end;');
+      AddToImplementation('');
+      TI.ReleaseTypeAttr(TA);
+      end;
+    end;
+end;
+
+Procedure TTypeLibImporter.CreateUnitHeader(Const TL : ITypeLib; const LA: lpTLIBATTR);
+
+
+Var
+  BstrName, BstrDocString, BstrHelpFile : WideString;
+  dwHelpContext: DWORD;
+
+begin
+  OleCheck(TL.GetDocumentation(-1, @BstrName, @BstrDocString, @dwHelpContext, @BstrHelpFile));
+  if (UnitName='') then
+    if FAppendVersionNumber then
+      UnitName:=format('%s_%d_%d_TLB',[BstrName,LA^.wMajorVerNum,LA^.wMinorVerNum])
+    else
+      UnitName:=format('%s_TLB',[BstrName]);
+  //header
+  AddToHeader('Unit %s;',[UnitName],True);
+  AddToHeader('',true);
+  AddToHeader('//  Imported %s on %s from %s',[BstrName,DateTimeToStr(Now()),InputFilename],True);
+  AddToHeader('',true);
+  AddToHeader('{$mode delphi}{$H+}',true);
+  AddToHeader('',true);
+  AddToHeader('interface',true);
+  AddToHeader('',true);
+  FUses.Add('Windows');
+  FUses.Add('ActiveX');
+  FUses.Add('Classes');
+  FUses.Add('OleServer');
+  FUses.Add('Variants');
+  AddToInterface('Const');
+  AddToInterface('  %sMajorVersion = %d;',[BstrName,LA^.wMajorVerNum]);
+  AddToInterface('  %sMinorVersion = %d;',[BstrName,LA^.wMinorVerNum]);
+  AddToInterface('  %sLCID = %x;',[BstrName,LA^.LCID]);
+  AddToInterface('  LIBID_%s : TGUID = ''%s'';',[BstrName,GUIDToString(LA^.GUID)]);
+  AddToInterface('');
+end;
+
+Procedure TTypeLibImporter.DoImportTypelib;
+
+var
+  TL: ITypelib;
+  TIcount:integer;
+  LA: lpTLIBATTR;
+
+begin
+  Header.Clear;
+  InterfaceSection.Clear;
+  OleCheck(LoadTypeLib(PWidechar(InputFileName), TL ));
+  OleCheck(TL.GetLibAttr(LA));
+  try
+    CreateUnitHeader(TL,LA);
+    TIcount:=TL.GetTypeInfoCount;
+    ImportGUIDs(TL,TICount);
+    ImportEnums(TL,TICount);
+    CreateForwards(TL,TICount);
+    CreateRecordsUnionsAliases(TL,TICount);
+    CreateInterFaces(TL,TICount);
+    CreateCoClasses(TL,TICount);
+  finally
+    TL.ReleaseTLibAttr(LA);
+  end;
+  BuildUnit;
+end;
+
+procedure TTypeLibImporter.BuildUnit;
+
+Var
+  l : string;
+  I : Integer;
+
+begin
+  UnitSource.AddStrings(Header);
+  UnitSource.Add('Uses');
+  L:='  ';
+  For I:=0 to FUses.Count-1 do
+    begin
+    L:=L+FUses[i];
+    If (I<Fuses.Count-1) then
+      L:=L+','
+    else
+      L:=L+';';
+    if (Length(L)>72) then
+      begin
+      UnitSource.Add(L);
+      L:='  ';
+      end;
+    end;
+  if (L<>'  ') then
+    UnitSource.Add(L);
+  UnitSource.addStrings(InterfaceSection);
+  UnitSource.addStrings(ImplementationSection);
+  UnitSource.Add('end.');
+end;
+
+{ TTypeLibImporter }
+
+procedure TTypeLibImporter.SetOutputFileName(AValue: String);
+
+Var
+  UN : String;
+
+begin
+  if FOutputFileName=AValue then Exit;
+  UN:=ChangeFileExt(ExtractFileName(AValue),'');
+  if not IsValidIdent(UN) then
+    Raise Exception.CreateFmt(SErrInvalidUnitName,[UN]);
+  FOutputFileName:=AValue;
+  SetUnitName(UN)
+end;
+
+procedure TTypeLibImporter.SetUnitName(AValue: string);
+begin
+  if FUnitname=AValue then Exit;
+  if not IsValidIdent(AVAlue) then
+    Raise Exception.CreateFmt(SErrInvalidUnitName,[AValue]);
+  FUnitname:=AValue;
+  if (OutputFileName<>'') then
+    OutputFileName:=ExtractFilePath(OutputFileName)+UnitName+'.pas';
+end;
+
+procedure TTypeLibImporter.AddToUses(const AUnit: String);
+begin
+  If FUses.IndexOf(AUnit)=-1 then
+    FUses.add(AUnit);
+end;
+
+procedure TTypeLibImporter.AddToHeader(const ALine: String;
+  AllowDuplicate: Boolean);
+
+begin
+  If (AllowDuplicate) or (FHeader.IndexOf(ALine)=-1) then
+    FHeader.Add(ALine);
+end;
+
+procedure TTypeLibImporter.AddToHeader(const Fmt: String; Args: array of const;
+  AllowDuplicate: Boolean);
+begin
+  AddToheader(Format(Fmt,Args),AllowDuplicate)
+end;
+
+procedure TTypeLibImporter.AddToInterface(const ALine: String);
+begin
+  FInterface.Add(ALine);
+end;
+
+procedure TTypeLibImporter.AddToInterface(const Fmt: String;
+  Args: array of const);
+begin
+  FInterface.Add(Format(Fmt,Args));
+end;
+
+procedure TTypeLibImporter.AddToImplementation(const ALine: String);
+begin
+  FImplementation.Add(ALine);
+end;
+
+procedure TTypeLibImporter.AddToImplementation(const Fmt: String;
+  Args: array of const);
+begin
+  FImplementation.Add(Format(Fmt,Args));
+end;
+
+constructor TTypeLibImporter.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  FDependencies:=TStringList.Create;
+  FUnitSource:=TStringList.Create;
+  FAppendVersionNumber:=true;
+end;
+
+destructor TTypeLibImporter.Destroy;
+begin
+  FreeAndNil(FDependencies);
+  FreeAndNil(FUnitSource);
+  inherited Destroy;
+end;
+
+procedure TTypeLibImporter.Execute;
+begin
+  FDependencies.Clear;
+  FUnitSource.Clear;
+  FHeader:=TStringList.Create;
+  FInterface:=TStringList.Create;
+  FImplementation:=TStringList.Create;
+  FUses:=TStringList.Create;
+  try
+    DoImportTypeLib;
+    If (OutputFileName<>'') then
+      UnitSource.SaveToFile(OutputFileName);
+  finally
+    FreeAndNil(FUses);
+    FreeAndNil(FInterface);
+    FreeAndNil(FHeader);
+    FreeAndNil(FImplementation);
+  end;
+end;
+
+end.
+

Some files were not shown because too many files changed in this diff