This chapter describes how to create and edit type libraries using Delphi's Type Library editor. Type libraries are files that include information about data types, interfaces, member functions, and object classes exposed by an ActiveX control or server. Type libraries provide a way for you to identify what types of objects and interfaces are available on your ActiveX server. For a detailed overview on why and when to use type libraries, see "Overview of COM technologies."
By including a type library with your COM application or ActiveX library, you make information about the objects in your COM application available to other applications and programming tools.
With traditional development tools, you create type libraries by writing scripts in the Interface Definition Language (IDL) or the Object Description Language (ODL), then run that script through a compiler. With the Type Library editor, Delphi automates some of this process, easing the burden of creating your own type libraries.
If you create your COM object, ActiveX control, or Automation object using a wizard, the Type Library editor automatically generates the Pascal syntax for your existing object. Then you can easily refine your type library information using the Type Library editor. As you modify the type library using the Type Library editor, changes can be automatically updated in the associated object, or you can review and veto those changes, if the is enabled. (See "Apply Updates dialog" for details.)
You can also use the Delphi Type Library Editor in the development of Common Object Request Broker Architecture (CORBA) applications. With traditional CORBA tools, you must define object interfaces separately from your application, using the CORBA Interface Definition Language (IDL). You then run a utility that generates stub-and-skeleton code from that definition. However, Delphi generates the stub, skeleton, and IDL for you automatically. You can easily edit your interface using the Type Library editor and Delphi automatically updates the appropriate source files. For more information on CORBA, see "Writing CORBA applications."
A type library can contain any and all of the following:
This chapter concludes with information on
The Type Library editor is a tool that enables developers to examine and create type information for ActiveX controls and COM objects.
Figure 50.1 shows the Type Library editor displaying type information for an ActiveX button control.
The main elements of the Type Library editor are
The Type Library editor's toolbar located at the top of the Type Library Editor, contains buttons that you click to add new objects into your type library.
You can add the following object types from the toolbar:
| A type library. This can be expanded to expose the individual type information, including objects and interfaces. |
| |
| |
| |
| |
| |
| |
| |
| |
| A method of the interface, dispinterface, or an entry point in a module. |
| |
| |
| |
| |
| |
|
The icons in the left box, Interface, Dispatch, CoClass, Enum, Alias, Record, Union, and Module represent the type info objects that you can edit.
When you click a toolbar button, the icon of that information type appears at the bottom of the object list pane. You can then customize its attributes in the right pane. Depending on the type of icon you selected, different pages of information appear to the right.
When you select an object, the Type Library editor displays which members are valid for that object. These members appear on the toolbar in the second box. For example, when you select Interface, the Type Library editor displays Method and Property icons in the second box because you can add methods and properties to your interface definition. When you select Enum, the Type Library editor displays the Const member, which is the only valid member for Enum type information.
In the third box, you can choose to refresh, register, or export your type library, as described in "Saving and registering type library information".
The Object list pane displays all the elements of the current type library, beginning with its interfaces. The interfaces expand to show the properties, methods, and events specified for that interface:
The context menu for the Object list pane provides the following options:
When editing or saving a type library, syntax, translation errors, and warnings are listed in the Status bar pane.
For example, if you specify a type that the Type Library editor does not support, you will get a syntax error. For a complete list of types supported by the Type Library editor, see "Valid types".
When you select an object in the object list pane, pages of type information appear in the Type Library editor that are valid for the selected object. Which pages appear depends on the object selected in the object list panel as follows:
All type library elements have attributes pages, which allow you to define a name and other attributes specific to the element. For example, if you have an interface selected, you can specify the GUID and parent interface. If you have a field selected, you can specify its type. Subsequent sections describe the attributes for each type library element in detail.
Attributes common to all elements in the type library are those associated with help. It is strongly recommended that you use the help strings to describe the elements in your type library to make it easier for applications using the type library.
The Type Library editor supports two mechanisms for supplying help. The traditional help mechanism, where a standard windows help file has been created for the library, or where the help information is located in a separate DLL (for localization purposes).
The following help attributes can apply to all elements:
Note: The help file must be supplied separately by the developer.
All type library elements have a text page that displays the syntax for the element. This syntax appears in an IDL subset of Microsoft Interface Definition Language, or Object Pascal. Any changes you make in other pages of the element are reflected on the text page. If you add code directly in the text page, changes are reflected in the other pages of the Type Library editor.
The Type Library editor will generate syntax errors if you add identifiers that are currently not supported by the editor; the editor currently supports only those identifiers that relate to type library support (not RPC support or constructs used by the Microsoft IDL compiler for C++ code generation or marshalling support).
Some type library elements have flags that allow you to enable or disable certain characteristics or implied capabilities. Subsequent sections describe the flags for each type library element in detail.
When the type library (top-most node) is selected in the Object list pane, you can change type information for the type library itself by modifying the following pages:
The Attributes page displays type information about the currently selected type library:
The Uses page lists the names and locations of any other type libraries that this type library references.
The following flags appear on the flags page when a type library is selected. It specifies how other applications must use the server associated with this type library:
The interface describes the methods (and any properties expressed as 'get' and 'set' functions) for an object that must be accessed through a virtual function table (VTable). If an interface is flagged as dual, which is the default, a dispinterface is also implied and can be accessed through OLE automation.
You can modify a type library interface by
The Attributes page lists the following type information:
The following flags are valid when an interface is selected in the main object pane.
The Type Library editor allows you to define new or modify existing
You can also change property and method parameters with the Parameters page.
The interface is more commonly used than the dispinterface to describe the properties and methods of an object.
Members of interfaces that need to raise exceptions should return an HRESULT and specify a return value parameter (PARAM_RETVAL) for the actual return value. Declare these methods using the safecall calling convention.
When you select the Method icon to add a new method, the Type Library editor displays the valid pages for a method: attributes, parameters, flags, and text.
The attributes for an interface method are as follows:
You supply parameters for methods as described in "Property and method parameters page".
The flags for an interface method are as follows:
Properties for interfaces are represented by the 'get' and 'set' methods used to read and write the property's underlying data. They are represented in the tree view using special icons that indicate their purpose.
Note: ActiveX properties specified as Write By Reference means the property is passed as a pointer rather by value. Some applications, such a Visual Basic, use the Write By Reference, if it is present, to optimize performance. To pass the property only by reference rather than by value, use the property type, By Reference Only. To pass the property by reference as well as by value, select Read|Write|Write By Ref. To invoke this menu, go to the toolbar and select the arrow next to the property icon.
The attributes for an interface property are as follows:
Type of property; this can be any valid type as specified in "Valid types". | |
Indicates whether this property is a getter function, putter function, or putter by reference. |
The flags that you can set for an interface property are as follows:
The parameters page allows you to specify the parameters and return values for your functions.
For property functions, the property type is derived from either the return type or the last parameter. Changing the type on the parameters page affects the property type displayed on the attributes page. Likewise, changing the type displayed on the attributes page, affects the contents of the parameters page.
Note: Changing one property function affects any related property functions. The Type Library editor assumes that property functions are related if they have the same name and Dispatch ID.
The parameters page differs, depending on whether you are working in IDL or Object Pascal.
When you add a parameter, if you are working in Object Pascal, the Type Library editor supplies the following:
If you are working in IDL, the Type Library editor supplies the following:
You can change the name by typing a new name. Change the type by choosing a new value from the drop-down list. The possible values for type are those supported by the Type Library editor as listed in "Valid types".
If you are working in Object Pascal, change the modifier by choosing a new value from the drop-down list. The possible values are as follows:
Use the default column to specify default parameter values. When you add a default, the Type Library editor automatically adds the appropriate flags to the type library.
To change a parameter flag (when working in IDL), double-click the Modifier field to go to the Parameters flag dialog box. You can select from the following parameter flags:
Note: When working in IDL, default values are specified using flags rather than in a separate column. Also, local IDs are specified using a flag rather than using a parameter type specifier of TLCID.
You can use the Move Up and Move Down buttons to change the order of your parameters. However, the editor will not change the order if the move breaks a rule of the IDL language. For example, the Type Library editor enforces the rule that return values must always be the last parameter in the parameter list.
Interfaces are more commonly used than dispinterfaces to describe the properties and methods of an object. Dispinterfaces are only accessible through dynamic binding, while interfaces can have static binding through a vtable.
You can modify a dispatch interface (dispinterface) by
The following attributes apply to the dispinterface:
The flags page for Dispatch is the same as for Interface. See "Interface flags".
For your dispinterface, you can define
How you add methods and properties for dispinterfaces is the same as how you add them for interfaces, as described in "Property and method parameters page".
Notice that when you create a property for a dispinterface, you can no longer specify a function kind or parameter types. Dispinterface method and property flags are the same as those for an interface as described in "Interface methods" and "Interface properties".
The CoClass describes a unique COM object which implements one or more interfaces and specifies which implemented interface is the default for the object, and optionally, which dispinterface is the default source for events.
You can modify a CoClass definition in the type library by
The attributes page that apply for the CoClass are as follows:
The Implements page is used to specify what interfaces and dispinterfaces are implemented for the CoClass. For each interface, the Implements page specifies whether the following items are supported:
The implements page's context menu contains menu items to toggle the above options. The 'Insert interface' menu option brings up a dialog where you can choose an interface to add to the CoClass. The list includes interfaces that are defined in the current type library and interfaces defined in any type libraries that the current type library references.
The following flags are valid when a CoClass is selected in the main object pane.
You can add or modify an Enumeration definition in the type library by
The attributes page that apply to an enum are as follows:
It is strongly recommended that you provide a help string for your enumerations to make their meaning clearer. The following is a sample entry of an enumeration type for a mouse button and includes a help string for each enumeration element.
mbLeft = 0 [helpstring 'mbLeft']; mbRight = 1 [helpstring 'mbRight']; mbMiddle = 3 [helpstring 'mbMiddle'];
Enums are comprised of a list of constants, which must be numeric. Numeric input is usually an integer in decimal or hexadecimal format. The base value is zero by default.
To define constants for your enum, click the New Const button.
An alias creates an alias (type definition) for a type. You can use the alias to define types that you want to use in other type info such as records or unions.
You can create or modify an alias definition in the type library by
The attributes page for an alias contains the following
You can add or modify a record definition in the type library by
The attributes page for a record contain the following
A record is comprised of a list of structure members or fields. A field has a
Members can be of any built-in type, or you can specify a type using alias before you define the record.
Records can be defined with an optional tag.
A union is a record with only a variant part.
You can add or modify a union definition in the type library by
The attributes page for a union contain the following
A union, like a record, is comprised of a list of structure members or fields. A field has the following parts:
Members can be of any built-in type, or you can specify a type using alias before you define the record.
Unions can be defined with an optional tag.
The module defines a group of functions, typically a set of DLL entry points.
You can create or modify a module definition in the type library by
Note: Delphi does not automatically generate any declarations or implementation related to the module. The specified DLL is created by the user as a separate project.
The attributes page for a module contains the following
Module methods have the following attributes:
You supply parameters for module methods in the same way you supply interface parameters, which are described in "Property and method parameters page".
To define constants for your module, you supply the following:
A module constant can be either a numeric or a string, depending on the attribute. Numeric input is usually an integer in decimal or hexadecimal format; it can also be a single char constant (such as \0). String input is delimited by double quotation marks (""), and cannot span multiple lines. The backslash is an escape character. The backslash character followed by another character, including another backslash, prevents the second character from being interpreted with any special meaning. For example, to put a backslash into text, use:
"Pathname: c:\\bin\\"
The Type Library editor enables you to create type libraries for ActiveX controls, ActiveX servers and other COM objects.
The editor supports a subset of valid types and safe arrays in a type library as described below.
This section describes how to:
In the Type Library editor, you use different type identifiers, depending on whether you are working in IDL or Object Pascal. Specify the language you want to use in the Environment options dialog.
The following types are valid in a type library for COM development. The Automation compatible column specifies whether the type can be used by an interface that has its Automation or DispInterface flag checked. These are the types that COM can marshal via the type library automatically.
* Word, LongWord, SYSINT, and SYSUINT may be Automation-compatible with some applications.
Note: For valid types for CORBA development, see "Writing CORBA applications."
Note: Byte (VT_UI1) is Automation-compatible, but is not allowed in a Variant or OleVariant since many Automation servers do not handle this value correctly.
Besides these types, any interfaces and types defined in the library or defined in referenced libraries can be used in a type library definition.
The Type Library editor stores type information expressed in the Interface Definition Language (IDL) syntax in the generated type library (.TLB) file in binary form.
If the parameter type is preceded by a Pointer type, the Type Library editor usually translates that type into a variable parameter. When the type library is saved, the variable parameter's associated ElemDesc's IDL flags are marked IDL_FIN or IDL_FOUT.
Often, ElemDesc IDL flags are not marked by IDL_FIN or IDL_FOUT when the type is preceded with a Pointer. Or, in the case of dispinterfaces, IDL flags are not typically used. In these cases, you may see a comment next to the variable identifier such as {IDL_None} or {IDL_In}. These comments are used when saving a type library to correctly mark the IDL flags.
COM requires that arrays be passed via a special data type known as a SafeArray. You can create and destroy SafeArrays by calling special COM functions to do so, and all elements within a SafeArray must be valid automation-compatible types. The Delphi compiler has built-in knowledge of COM SafeArrays and will automatically call the COM API to create, copy, and destroy SafeArrays.
In the Type Library editor, a SafeArray must specify its component type. For example, in the following code, the SafeArray specifies a component type of Integer:
procedure HighLightLines(Lines: SafeArray of Integer);
The component type for a SafeArray must be an Automation-compatible type. In the Object Pascal type library translation unit, the component type is not necessary or allowed.
By default, the Text page of the Type Library editor displays your type information using an extension of Object Pascal syntax. You can work directly in IDL instead by changing the setting in the Environment Options dialog. Choose Tools|Environment Options, and specify IDL as the Editor language on the Type Library page of the dialog.
Note: The choice of Object Pascal or IDL syntax also affects the choices available on the parameters attributes page.
Like Object Pascal applications in general, identifiers in type libraries are case insensitive. They can be up to 255 characters long, and must begin with a letter or an underscore (_).
Object Pascal has been extended to allow type libraries to include attribute specifications. Attribute specifications appear enclosed in square brackets and separated by commas. Each attribute specification consists of an attribute name followed (if appropriate) by a value.
The following table lists the attribute names and their corresponding values.
The Object Pascal syntax for declaring interface type information has the form
interfacename = interface[(baseinterface)] [attributes] functionlist [propertymethodlist] end;
For example, the following text declares an interface with two methods and one property:
Interface1 = interface (IDispatch)
[uuid '{7B5687A1-F4E9-11D1-92A8-00C04F8C8FC4}', version 1.0]
function Calculate(optional seed:Integer=0): Integer;
procedure Reset;
procedure PutRange(Range: Integer) [propput, dispid $00000005]; stdcall;
function GetRange: Integer;[propget, dispid $00000005]; stdcall;
end;
The corresponding syntax in IDL is
[uuid '{5FD36EEF-70E5-11D1-AA62-00C04FB16F42}',version 1.0]
interface Interface1 :IDispatch
{
long Calculate([in, optional, defaultvalue(0)] long seed);
void Reset(void);
[propput, id(0x00000005)] void _stdcall PutRange([in] long Value);
[propput, id(0x00000005)] void _stdcall getRange([out, retval] long *Value);
};
The Object Pascal syntax for declaring dispinterface type information has the form
dispinterfacename = dispinterface [attributes] functionlist [propertylist] end;
For example, the following text declares a dispinterface with the same methods and property as the previous interface:
MyDispObj = dispinterface
[uuid '{5FD36EEF-70E5-11D1-AA62-00C04FB16F42}',
version 1.0,
helpstring 'dispatch interface for MyObj']
function Calculate(seed:Integer): Integer [dispid 1];
procedure Reset [dispid 2];
property Range: Integer [dispid 3];
end;
The corresponding syntax in IDL is
[uuid '{5FD36EEF-70E5-11D1-AA62-00C04FB16F42}',
version 1.0,
helpstring "dispatch interface for MyObj"]
dispinterface Interface1
{
methods:
[id(1)] int Calculate([in] int seed);
[id(2)] void Reset(void);
properties:
[id(3)] int Value;
};
The Object Pascal syntax for declaring CoClass type information has the form
classname = coclass(interfacename[interfaceattributes], ...); [attributes];
For example, the following text declares a coclass for the interface IMyInt and dispinterface DmyInt:
myapp = coclass(IMyInt [source], DMyInt);
[uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}',
version 1.0,
helpstring 'A class',
appobject]
The corresponding syntax in IDL is
[uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}',
version 1.0,
helpstring 'A class',
appobject]
coclass myapp
{
methods:
[source] interface IMyInt);
dispinterface DMyInt;
};
The Object Pascal syntax for declaring Enum type information has the form
enumname = ([attributes] enumlist);
For example, the following text declares an enumerated type with three values:
location = ([uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}',
helpstring 'location of booth']
Inside = 1 [helpstring 'Inside the pavillion'];
Outside = 2 [helpstring 'Outside the pavillion'];
Offsite = 3 [helpstring 'Not near the pavillion'];);
The corresponding syntax in IDL is
[uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}',
helpstring 'location of booth']
typedef enum
{
[helpstring 'Inside the pavillion'] Inside = 1,
[helpstring 'Outside the pavillion'] Outside = 2,
[helpstring 'Not near the pavillion'] Offsite = 3
} location;
The Object Pascal syntax for declaring Alias type information has the form
aliasname = basetype[attributes];
For example, the following text declares DWORD as an alias for integer:
DWORD = Integer [uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}'];
The corresponding syntax in IDL is
[uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}'] typedef long
DWORD;
The Object Pascal syntax for declaring Record type information has the form
recordname = record [attributes] fieldlist end;
For example, the following text declares a record:
Tasks = record [uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}',
helpstring 'Task description']
ID: Integer;
StartDate: TDate;
EndDate: TDate;
Ownername: WideString;
Subtasks: safearray of Integer;
end;
The corresponding syntax in IDL is
[uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}',
helpstring 'Task description']
typedef struct
{
long ID;
DATE StartDate;
DATE EndDate;
BSTR Ownername;
SAFEARRAY (int) Subtasks;
} Tasks;
The Object Pascal syntax for declaring Union type information has the form
unionname = record [attributes] case Integer of 0: field1; 1: field2; ... end;
For example, the following text declares a union:
MyUnion = record [uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}',
helpstring 'item description']
case Integer of
0: (Name: WideString);
1: (ID: Integer);
3: (Value: Double);
end;
The corresponding syntax in IDL is
[uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}',
helpstring 'item description']
typedef union
{
BSTR Name;
long ID;
double Value;
} MyUnion;
The Object Pascal syntax for declaring Module type information has the form
modulename = module constants entrypoints end;
For example, the following text declares the type information for a module:
MyModule = module [uuid
'{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}',
dllname 'circle.dll']
PI: Double = 3.14159;
function area(radius: Double): Double [ entry 1 ]; stdcall;
function circumference(radius: Double): Double [ entry 2 ]; stdcall;
end;
The corresponding syntax in IDL is
[uuid '{2MD36ABF-90E3-11D1-AA75-02C04FB73F42}',
dllname("circle.dll")]
module MyModule
{
double PI = 3.14159;
[entry(1)] double _stdcall area([in] double radius);
[entry(2)] double _stdcall circumference([in] double radius);
};
You may want to create a type library that is independent of an ActiveX control, for example, if you want to define a type library for an ActiveX control that is not yet implemented.
The Type Library editor opens with a prompt to enter a name for the type library.
When you use the wizards to create an ActiveX control, Automation object, ActiveForm, COM object, MTS object, Remote Data Module, or MTS Data Module, a type library is automatically created with an implementation unit.
To open an existing type library independent of a project,
Or, to open a type library associated with the current project,
Now, you can add interfaces, CoClasses, and other elements of the type library such as enumerations, properties, and methods.
Note: Changes you make to any type library information with the Type Library editor can be automatically reflected in the associated ActiveX control. If you would prefer to review the changes beforehand, be sure that the Apply Updates dialog is on. It is on by default and can be changed in the setting, "Display updates before refreshing," on the Tools|Environment Options|Type Library page. For more information, see "Apply Updates dialog".
An interface is added to the object list pane prompting you to add a name.
The new interface contains default attributes that you can modify as needed. You can add properties (represented by getter/setter functions and methods to suit the purpose of the interface.
To add members to an interface or dispinterface,
An interface member is added to the object list pane prompting you to add a name.
The new member contains default attributes in its attributes page that you can modify to suit the member.
You can add properties and methods by typing directly into the text page using the Pascal syntax. For example, you can type the following property declarations into the text page of an interface:
property AutoSelect: WordBool; dispid 1; property AutoSize: WordBool; dispid 2; property BorderStyle: BorderStyle; dispid 3;
After you have added members to an interface member page, the members appear as separate items in the object list pane each with its own attributes page where you can modify each new member's attributes.
If you have the Apply Updates dialog enabled, the Type Library editor will notify you before updating the sources when you save the type library. and will warn you of potential problems. For example, if you rename an event by mistake, you will get a warning in your source file that looks like this:
Because of the presence of instance variables in your implementation file, Delphi was not able to update the file to reflect the change in your event interface name. As Delphi has updated the type library for you, however, you must update the implementation file by hand.
You will also get a TODO comment in your source file immediately above it.
Note: If you ignore this warning and TODO comment, the code will not compile.
To add a CoClass to a type library,
A CoClass is added to the object list pane prompting you to add a name.
The new class contains default attributes in its attributes page that you can modify to suit the class. To add members,
The list includes interfaces that are defined in the current type library and defined in any type libraries that the current type library references.
The interface is added to the page with with its GUID and other attributes.
To add enumerations to a type library,
An enum type is added to the object list pane prompting you to add a name.
The new enum is empty and contains default attributes in its attributes page for you to modify.
Add values to the enum by clicking on the New Const button. Then, select each enumerated value and assign its attributes using the attributes page.
After modifying your type library, you'll want to save and register the type library information. If the type library was created with one of the ActiveX server project types or objects, saving the type library automatically updates the binary type library, the Object Pascal code representing its contents, and the implementation code maintained for it.
The Type Library editor stores type library information in two formats:
This unit is the compilation of the declarations of the elements that are defined in the type library in Object Pascal terms. Delphi uses this unit to bind the type library as a resource in your .OCX or .EXE file. Make changes to the type library within the Type Library editor, as the editor generates these files each time you save the Type Library.
Note: The type library is stored as a separate binary (.TLB) file, but is also linked into the server (.EXE, DLL, or .OCX).
Note: When using the Type Library editor for CORBA interfaces, this unit defines the stub and skeleton objects required by the CORBA application.
The Type Library editor gives you options for storing your type library information, which way you choose depends on what stage you are at in implementing the type library:
All the above methods perform syntax checking. When you refresh, register, or save the type library, Delphi automatically updates the source file of the associated object. Optionally, you can review the changes before they are committed, if you have the Type Library editor option, Apply Updates on.
The Apply Updates dialog appears when you refresh, register, or save the type library if you have selected "Display updates before refreshing' in the Tools|Environment Options|Type Library page (which is on by default).
Without this option, the Type Library editor automatically updates the sources of the associated object when you make changes in the editor. With this option, you have a chance to veto the proposed changes when you attempt to refresh, save, or register the type library.
The Apply Updates dialog will warn you about potential errors, and will insert TODO comments in your source file. For example, if you rename an event by mistake, you will get a warning in your source file that looks like this:
Because of the presence of instance variables in your implementation file, Delphi was not able to update the file to reflect the change in your event interface name. As Delphi has updated the type library for you, however, you must update the implementation file by hand.
You will also get a TODO comment in your source file immediately above it.
Note: If you ignore this warning and TODO comment, the code will not compile.
To save the type library, choose File|Save from the Delphi main menu.
To refresh the type library choose the Refresh icon on the Type Library editor toolbar.
Note: If you have renamed or deleted items from the type library, refreshing the implementation may create duplicate entries. In this case, you must move your code to the correct entry and delete any duplicates.
To register the type library, choose the Register icon on the Type Library editor toolbar.
To export the type library, choose the Export icon on the Type Library editor toolbar.
By default, when you have a type library that was created as part of an ActiveX server project, the type library is automatically linked into the .DLL, .OCX, or EXE as a resource.
You can, however, deploy your application with the type library as a separate .TLB, as Delphi maintains the type library, if you prefer.
Historically, type libraries for Automation applications were stored as a separate file with the .TLB extension. Now, typical Automation applications compile the type libraries into the .OCX or .EXE file directly. The operating system expects the type library to be the first resource in the executable (.DLL, .OCX, or .EXE) file.
When you make type libraries other than the primary project type library available to application developers, the type libraries can