The TypeLib Browser is a tool designed to let you to examine the
contents of COM servers and ActiveX controls and to provide alternate
ways to use them or to give workarounds to features still not available
in the Power Basic compilers, such events sink.

Besides letting you to inspect all the information available in the
typelibs, it generates wrapper functions that use Direct VTable calls.

1.- If the "Ansi strings" box is checked, the functions will include
code to automatically convert string parameters to Unicode and returned
string values to Ansi.

2.- Checking the "Check null pointers" box the browser will add code
to check if pthis is null and exit the function or procedure with an
error code of %E_POINTER (&H80004003). This will protect you from GPFs
caused by null pointers.

3.- If the "DLL code" box is checked, the wrapper functions will be
aliased and exported, and the declares will be also aliased and include
the name of the DLL (the Prefix is used as the name; change it if needed
with a find and replace in your editor).

4.- If the "Automation" box is checked, information for dual interfaces
will be shown in the treeview using the IDispatch interface view instead
of the VTable view.

5.- If the "Use globals" box is checked, the functions will use a global
variable, <Prefix>_HRESULT to store the result code and, if the "DLL"
checkbox is also checked, two additional functions --<Prefix>Error and
<Prefix>Result-- are generated. Please note that this option isn't
intended for general use, but to make wrappers that can be tweaked to
make them easier to use. The Proto declares and the CALL DWORD must
remain unaltered, but the function header and the rest of the code can
be modified.

6. If the "Add enum prefix" box is checked, the name of the enumerations
are added to the constants. This is useful to avoid conflicts between
different enumerations having one or more members with the same name
that other enumerations.

7.- Double click the wanted typelib in the ListView to retrieve the
information.

8.- Click the Code button to generate the wrapper functions.

9.- If you have chosen to build a DLL, to use it you will need to
generate the declares with the Menu->Code->Declares option and save
them to a file.

10.- If the component fires events, you can generate code for events
sink with the Menu->Code->Events options. If there are more than one
events interface a dialog allows to select all of them or check the
ones you want. The generated class allows to sink events of multiple
instances of the same control; they are differentiated by the cookie,
which is the address of the address of the virtual table of the
generated class and that is passed as pCookie to all the event
functions. The pthis of the control is saved in the virtual table of
the class and retrieved in each function. You can use it to call
methods and properties of the control if you use prototypes or wrapper
functions, or you can convert it to a dispatch variable using
TB_MakeDispatchVariant (included in TB_COM32.INC) and use PB
Automation. To advise and unadvise from events sink use the generated
ConnectEvents/DisconnectEvents functions.

The events code uses HeapAlloc to allocate memory for the virtual
table of the class and HeapFree to release it. When you call the
<Prefix>_ConnectEvents function the reference counter is incremented
and when you call the <Prefix>_DisconnectEvents it is decremented.
If the reference counter is zero the memory is freed. To avoid memory
leaks or GPFs, each call to ConnectEvents must be matched with a call
to DisconnectEvents (using the cookie returned in the call to
ConnectEvents). A good place to call the ConnectEvents function is the
%WM_INITDIALOG (if you are using DDT) or %WM_CREATE (if you are using
SDK) messages. To call the <Prefix>_DisconnectEvents, a good place is
the %WM_DESTROY message. If you use this method, you can avoid the use
of global variables storing the cookies in static variables in the main
dialog callback (DDT) or main window procedure (SDK).

OTHER OPTIONS:
=============

The "Code" menu contains the following options:

"Enumerations": Generates a list of all the constants of all the
enumerations.

"Identifiers": Generates a list with all the ProgIDs, ClsIDs and IIDs.

"Declares": Generates the appropiate declarations to use the wrapper
functions.

"Prototypes": Generates all the code you can need to call the methods
and properties using direct VTable calls using CALL DWORD: ProgIDs,
enumerations, types and unions, VTables and declaration templates.

Assumming that lpRecordset has a valid reference to an ADO recordset,
you can call the methods and properties in three ways (the example uses
the get_State property):

a) If you have dimed lpRecordset as Dword Ptr:
CALL Dword @@lpRecordset[55] Using ADODBRecordset15_get_State(lpRecordset, plObjState) TO hr

b) If you have dimed lpRecordset as ADODBConnectionVtbl Ptr:
call Dword @@lpRecordset.get_State Using AdoRecordset15_get_State(lpRecordset, plObjState) to hr

c) If you have dimed lpRecordset as ADODBConnectionObject:
call Dword @lpRecordset.@lpVtbl.get_State Using AdoRecordset15_get_State(lpRecordset, plObjState) to hr

"VTables": Generates an structure (TYPE) for each interface containing
all the methods and properties of it.

"Modules": Modules can contain constants and declarations of external
functions. This option generates a list of the constants, that you can
copy and paste into your main code if needed. They aren't automatically
added to the constants relations because in many cases they belong to
external components or DLLs. It also generates declares for the functions.

"Structures": Generates declarations for all the structures (if any) in
the form TYPE/END TYPE.

"Typedefs": Generates a list of all the typedefs (if any) in the form
of macros.

"PB-like interfaces": These interfaces are intended to allow to use
PB Automation with components that the PB COM BRowser refuses because
don't have a ProgID, such Accessibility (OLEACC.DLL), or can't be found
in the registry, such TypeLib Information (TLBINF32.DLL).

"DispiDs": Generates equates with the DispID values in the form of
"%DispID_<Prefix><Interface name>_<method/property name>.

"Offsets": Generates equates with the VTable offsets in the form of
"%VTO_<Prefix><Interface name>_<method/property name>. A list of the
offsets for the standard IUnknown, IDispatch, IEnumVARIANT, IFont and
IPicture interfaces are included in the file TB_COM32.INC.

The "Events" menu includes the options "JACOM events (Automation) and
"JACOM events (IUnknown). They generate callback functions suitable to
be used with JACOMPB25. The diference among them is that the code
generated for Automation uses dispatch variables and the other pointers.


OTHER NOTES:
===========

The Menu->Open option allows to load typelibs --or DLLs, OCXs or EXE
files containing a typelib-- from disk. This is only useful when the
typelib is not registered.

The Menu->Save as... allows to save the generated code to a file.

The Menu->Reload TypeLibs option refreshes the list of registered
typelibs that appears in the ListView. This is only useful if you
register a new component while working with the browser.

The file TB_COM32.INC contains some important wrapper functions, such
TB_CreateObject, that lets you to create instances of any object
passing his ProgID or ClsID; IUnknown_Release, that lets you to
release any object or interface; TB_CreateControlLic, that lets you
to create instances of licensed OCXs and attach them to a window, and
AtlAxGetDispatch, that retrieves the dispatch interface of an OCX
giving the handle of the window that hosts it. Also declarations for
API functions to deal with variants and safearrays and a wrapper
function called TB_CallByName that allows you to call any method
or property giving his name and passing parameters as an array of
variants.

The file TB_ENUM.INC contains the source code for a collection's
enumerator and an example of how to use it.

Important notes:
===============

Some components, such Excel, have some functions with more than 31
parameters, that together with the pthis parameter exceed the maximum
of 32 parameters allowed by the PowerBasic compiler. These functions
will need to use another technique, such using assembler to push the
parameters in the stack.

When using ATL and OCXs, you must make sure that the %WM_DESTROY
message is processed when the user closes the application clicking
the x button. Use the following code (%WM_CLOSE always calls
%WM_DESTROY).

      CASE %WM_SYSCOMMAND
         ' Capture this message and send a %WM_CLOSE message
         ' or the program will remain in memory
         IF (wParam AND &HFFF0) = %SC_CLOSE THEN
            SendMessage hWnd, %WM_CLOSE, wParam, lParam
            EXIT FUNCTION
         END IF

Some parameters are marked as optional [opt], but when doing direct
VTable calls you have to pass all the parameters. If the optional
parameter is a Variant, you can't simply pass 0, "" or and EMPTY
variant, either pass the correct value or use a variant filled with
the value ERROR %DISP_E_PARAMNOTFOUND.

If the parameter is a variant and the value that it will contain is
a dispatch interface, use the helper function TB_MakeDispatchVariant
included in TB_COM32.INC.

If the parameter is a variant that must contain a boolean value, use
the helper function TB_MakeBoolVariant.
