Home COM GDI+ WebBrowser Data Access 

Automation

 

 

Automation (formerly called OLE Automation) is a technology that allows software packages to expose their unique features to scripting tools and other applications. Automation uses the Component Object Model (COM), but may be implemented independently from other OLE features, such as in-place activation. Using Automation, you can:

  • Create applications and programming tools that expose objects.

  • Create and manipulate objects exposed in one application from another application.

  • Create tools that access and manipulate objects. These tools can include embedded macro languages, external programming tools, object browsers, and compilers.

 

The objects an application or programming tool exposes are called ActiveX objects. Applications and programming tools that access those objects are called ActiveX clients. ActiveX objects and clients interact as follows:

 

Applications and other software packages that support ActiveX technology define and expose objects which can be acted on by ActiveX components. ActiveX components are physical files (for example .exe and .dll files) that contain classes, which are definitions of objects. Type information describes the exposed objects, and can be used by ActiveX components at either compile time or at run time.

 

Overview of Automation

© 2005 Microsoft Corporation. All rights reserved.

 

 

IDispatch Interface

 

IDispatch interface exposes objects, methods and properties to programming tools and other applications that support Automation. COM components implement the IDispatch interface to enable access by Automation clients, such as Visual Basic.

 

 

IEnumVARIANT Interface

 

The IEnumVARIANT interface provides a method for enumerating a collection of variants, including heterogeneous collections of objects and intrinsic types. Callers of this interface do not need to know the specific type (or types) of the elements in the collection.

 

 

Error Handling Interfaces

 

Objects that are invoked through virtual function table (VTBL) binding need to use the Automation error handling interfaces and API functions to define and return error information.

 

 

IErrorInfo Provides detailed contextual error information.

ICreateErrorInfo — Returns error information.

ISupportErrorInfo Ensures that error information can be propagated up the call chain correctly.

 

 

Type Building Interfaces

 

The type building interfaces, ICreateTypeInfo, ICreateTypeInfo2, ICreateTypeLib and ICreateTypeLib2, are used to build tools that automate the process of generating type descriptions and creating type libraries. The Microsoft Interface Definition Language (MIDL) compiler, for example, use these interfaces to create type libraries.

 

 

ICreateTypeLib - Provides the methods for creating and managing the component or file that contains type information.

ICreateTypeLib2 - Extends the ICreateTypeLib interface.

ICreateTypeInfo - Provides the tools for creating and administering the type information defined through the type description.

ICreateTypeInfo2 - Extends the ICreateTypeInfo interface.

 

 

Type Description Interfaces

 

Type description interfaces provide a way to read and bind to the descriptions of objects in a type library. These descriptions are used by ActiveX clients when they browse, create, and manipulate ActiveX (Automation) objects.

 

 

ITypeLib — Retrieves information about a type library.

ITypeLib2 — Contains additional type library retrieval actions.

ITypeInfo — Reads the type information within the type library.

ITypeInfo2 — Contains additional type information retrieval actions.

ITypeComp — Contains type lookup and binding methods.

 

 

User-Defined Data Types

 

User-defined data types (called user-defined types (UDT) in Microsoft® Visual Basic®, structures in languages like C and C++, and often referred to as records in general scenarios) are groups of related data items declared as one type of information. User-defined data types are very useful when you want to group several related pieces of information in a structured way.

 

However, there are limitations on using UDTs in Automation-based applications on computers running Microsoft® Windows® 95 without DCOM 1.2 or later or running Microsoft® Windows NT® 4.0 SP3 and earlier. Because user-defined types cannot be marshaled by these versions of Automation, UDTs could not be passed to generic Automation interface methods or functions. For example, if you had written interfaces that are available to Automation languages, such as Visual Basic, you could not use UDTs in those interfaces, because user-defined data types are unknown types to Automation and the remote procedure call subsystem (RPC). As a result, type-library driven marshaling was not possible for UDTs.

 

There are other ways to marshal UDTs. One way is to break down each field of the structure to an individual property. Unfortunately, this technique is relatively inefficient for the client and server because it requires each field in the structure to be passed one at a time. Another technique is to serialize the structure into a flat buffer that is placed into a safearray. This requires both the client and the server to deserialize the buffer back into the structure, a process that is tedious and prone to errors.

 

Beginning with Windows NT 4.0 SP4, Windows 95 with DCOM 1.2, and Windows 98, Automation now supports passing UDTs in variants and safearrays of user defined types as arguments to methods. This allows methods to return UDTs and allows programmers of Automation controllers (Automation clients) to call methods requiring pointers to structures.

 

See: User-Defined Data Types

© 2005 Microsoft Corporation. All rights reserved.

 

For information on how to pass single UDTs and safearrays of UDTs, see Passing UDTs.

 

For the methods, GetRecordInfoFromTypeInfo and GetRecordInfoFromGUID, used to create a self-describing array of records, see Support Functions for User-Defined Data Types.

 

For the member functions and descriptions of the IRecordInfo interface, see IRecordInfo Interface.

 

 

IRecordInfo — Describes the structure of a particular UDT.

 

 

 

Creation of Dispatch API Functions

 

CreateDispTypeInfo

 

Creates simplified type information for use in an implementation of IDispatch.

 

 

DECLARE FUNCTION CreateDispTypeInfo _

  LIB "OLEAUT32.DLL" _

  ALIAS "CreateDispTypeInfo" ( _

  BYREF pidata AS INTERFACEDATA _

, BYVAL lcid AS DWORD _

, BYREF pptinfo AS DWORD _

) AS LONG

 

CreateStdDispatch

 

Creates a standard implementation of the IDispatch interface through a single function call.

 

 

DECLARE FUNCTION CreateStdDispatch _

  LIB "OLEAUT32.DLL" _

  ALIAS "CreateStdDispatch" ( _

  BYVAL punkOuter AS DWORD _

, BYVAL pvThis AS DWORD _

, BYVAL ptinfo AS DWORD _

, BYREF ppunkStdDisp AS DWORD _

) AS LONG

 

DispGetIDsOfNames

 

Uses type information to convert a set of names to DISPIDs.

 

 

DECLARE FUNCTION DispGetIDsOfNames _

  LIB "OLEAUT32.DLL" _

  ALIAS "DispGetIDsOfNames" ( _

  BYVAL ptinfo AS DWORD _

, BYREF rgszNames AS STRING _

, BYVAL cNames AS DWORD _

, BYREF rgdispid AS LONG _

) AS LONG

 

DispGetparam

 

Retrieves a parameter from the DISPPARAMS structure, checking both named parameters and positional parameters, and coerces the parameter to the specified type.

 

 

DECLARE FUNCTION DispGetParam _

  LIB "OLEAUT32.DLL" _

  ALIAS "DispGetParam" ( _

  BYREF pdispparams AS DISPPARAMS _

, BYVAL position AS DWORD _

, BYVAL vtTarg AS WORD _

, BYREF pvarResult AS ANY _

, BYREF puArgErr AS DWORD _

) AS LONG

 

DispCallFunc

 

Low-level helper for IDispatch::Invoke() that provides machine independence for customized Invoke().

 

 

DECLARE FUNCTION DispCallFunc _

  LIB "OLEAUT32.DLL" _

  ALIAS "DispCallFunc" ( _

  BYVAL pvInstance AS DWORD _

, BYVAL oVft AS DWORD _

, BYVAL cc AS LONG _

, BYVAL vtReturn AS WORD _

, BYVAL cActuals AS DWORD _

, BYREF prgvt AS WORD _   ' array of variant types

, BYREF prgpvarg AS ANY _   ' array of variants

, BYREF pvargResult AS ANY _   ' Variant

) AS LONG

 

DispInvoke

 

Automatically calls member functions on an interface, given the type information for the interface. You can describe an interface with type information and implement IDispatch::Invoke for the interface using this single call.

 

 

DECLARE FUNCTION DispInvoke _

  LIB "OLEAUT32.DLL" _

  ALIAS "DispInvoke" ( _

  BYVAL pthis AS DWORD _

, BYVAL ptinfo AS DWORD _

, BYVAL dispidMember AS LONG _

, BYVAL wFlags AS WORD _

, BYREF pparams AS DISPPARAMS _

, BYREF pvarResult AS ANY _

, BYREF pexcepinfo AS EXCEPINFO _

, BYREF puArgErr AS DWORD _

) AS LONG

 

 

PARAMDATA Structure

 
Used to describe a parameter accepted by a method or property.
 
TYPE PARAMDATA
   szName AS DWORD
   vt AS WORD
   vtFill AS WORD   ' To keep DWORD alignment
END TYPE
 

METHODDATA Structure

 
Used to describe a method or property.
 
TYPE METHODDATA
   szName AS DWORD
   ppdata AS PARAMDATA PTR
   dispid AS LONG
   iMeth AS DWORD
   cc AS DWORD
   cArgs AS DWORD
   wFlags AS WORD
   vtReturn AS WORD
END TYPE
 

INTERFACEDATA Structure

 
Describes the ActiveX object's properties and methods.
 
TYPE INTERFACEDATA
   pmethdata AS METHODDATA PTR
   cMembers AS LONG
END TYPE
 

 

Sample code

 

Creates simplified type information for use in an implementation of IDispatch.


Note: VB uses some conventions for the dispids, e.g. %DISPID_VALUE (0) for the default property (the one that can be ommited, generally named "Value", "Item" or "Text").

 

 

FUNCTION MyClass_CreateDispTypeInfo (BYREF pptinfo AS DWORD) AS LONG

   DIM rgadata(2) AS STATIC METHODDATA
   DIM rgaSetRatePrmData (0) AS STATIC PARAMDATA
   DIM rgaTaxItPrmData (0) AS STATIC PARAMDATA
   STATIC strRate AS STRING

   strRate = UCODE$("RATE")
   STATIC strTaxIt AS STRING
   strTaxIt = UCODE$("TAXIT")

   ' ==================================================
   ' GetRate property
   ' ==================================================
   rgadata(0).szName = VARPTR(strRate)
   rgadata(0).ppdata = %NULL
   rgadata(0).dispid = 1
   rgadata(0).imeth = 0
   rgadata(0).cc = 4 ' STDCALL
   rgadata(0).cArgs = 0
   rgadata(0).wFlags = 2 ' %DISPATCH_PROPERTYGET
   rgadata(0).vtReturn = %VT_R8 ' Double

   ' ==================================================
   ' SetRate property
   ' ==================================================
   STATIC strRatePrmName AS STRING
   strRatePrmName = UCODE$("dlRate")
   rgaSetRatePrmData(0).szName = VARPTR(strRatePrmName)
   rgaSetRatePrmData(0).vt = %VT_R8 ' Double
   rgadata(1).szName = VARPTR(strRate)
   rgadata(1).ppdata = VARPTR(rgaSetRatePrmData(0))
   rgadata(1).dispid = 1
   rgadata(1).imeth = 1
   rgadata(1).cc = 4 ' STDCALL
   rgadata(1).cArgs = 1
   rgadata(1).wFlags = 4 ' %DISPATCH_PROPERTYPUT
   rgadata(1).vtReturn = %VT_VOID ' no retun value

   ' ==================================================
   ' TaxIt method
   ' ==================================================
   STATIC strPricePrmName AS STRING
   strPricePrmName = UCODE$("dlPrice")
   rgaTaxItPrmData(0).szName = VARPTR(strPricePrmName)
   rgaTaxItPrmData(0).vt = %VT_R8 ' Double
   rgadata(2).szName = VARPTR(strTaxIt)
   rgadata(2).ppdata = VARPTR(rgaTaxItPrmData(0))
   rgadata(2).dispid = 2
   rgadata(2).imeth = 2
   rgadata(2).cc = 4 ' STDCALL
   rgadata(2).cArgs = 1
   rgadata(2).wFlags = 1 ' %DISPATCH_METHOD
   rgadata(2).vtReturn = %VT_R8 ' Double

   LOCAL hr AS LONG
   hr = CreateDispTypeInfo(BYVAL VARPTR(rgadata(0)), %LOCALE_SYSTEM_DEFAULT, pptinfo)

END FUNCTION

 

 

 

API Functions to Register the Active Object

 

GetActiveObject

 

Retrieves a pointer to a running object that has been registered with OLE.

 

 

DECLARE FUNCTION GetActiveObject _

  LIB "OLEAUT32.DLL" _

  ALIAS "GetActiveObject" ( _

  BYREF rclsid AS GUID _

, BYVAL pvReserved AS DWORD _

, BYREF ppunk AS DWORD _

) AS LONG

 

RegisterActiveObject

 

Registers an object as the active object for its class.

 

 

DECLARE FUNCTION RegisterActiveObject _

  LIB "OLEAUT32.DLL" _

  ALIAS "RegisterActiveObject" ( _

  BYVAL punk AS DWORD _

, BYREF rclsid AS GUID _

, BYVAL dwFlags AS DWORD _

, BYREF pdwRegister AS DWORD _

) AS LONG

 

RevokeactiveObject

 

Ends an object's status as active.

 

 

DECLARE FUNCTION RevokeactiveObject _

  LIB "OLEAUT32.DLL" _

  ALIAS "RevokeactiveObject" ( _

  BYVAL dwRegister AS DWORD _

, BYVAL pvReserved AS DWORD _

) AS LONG

 

 

 

Error Handling API Functions

 

CreateErrorInfo

 

Creates an instance of a generic error object. This function returns a pointer to a generic error object, which you can use with QueryInterface on ICreateErrorInfo to set its contents. You can then pass the resulting object to SetErrorInfo. The generic error object implements both ICreateErrorInfo and IErrorInfo.

 

 

DECLARE FUNCTION CreateErrorInfo _

  LIB "OLEAUT32.DLL" _

  ALIAS "CreateErrorInfo" ( _

  BYREF pperrinfo AS DWORD _

) AS LONG

 

GetErrorInfo

 

Obtains the error information pointer set by the previous call to SetErrorInfo in the current logical thread.

 

This function returns a pointer to the most recently set IErrorInfo pointer in the current logical thread. It transfers ownership of the error object to the caller, and clears the error state for the thread.

Making a COM call that goes through a proxy-stub will clear any existing error object for the calling thread. A called object should not make any such calls after calling SetErrorInfo and before returning. The caller should not make any such calls after the call returns and before calling GetErrorInfo. As a rule of thumb, an interface method should return as soon as possible after calling SetErrorInfo, and the caller should call GetErrorInfo as soon as possible after the call returns.

 

 

DECLARE FUNCTION GetErrorInfo _

  LIB "OLEAUT32.DLL" _

  ALIAS "GetErrorInfo" ( _

  BYVAL dwReserved AS DWORD _

, BYREF pperrinfo AS DWORD _

) AS LONG

 

SetErrorInfo

 

Sets the error information object for the current logical thread of execution.

 

This function releases the existing error information object, if one exists, and sets the pointer to perrinfo. Use this function after creating an error object that associates the object with the current logical thread of execution.

 

If the property or method that calls SetErrorInfo is called by DispInvoke, then DispInvoke will fill the EXCEPINFO parameter with the values specified in the error information object. DispInvoke will return DISP_E_EXCEPTION when the property or method returns a failure return value for DispInvoke.

 

Virtual function table (VTBL) binding controllers that do not use IDispatch::Invoke can get the error information object by using GetErrorInfo. This allows an object that supports a dual interface to use SetErrorInfo, regardless of whether the client uses VTBL binding or IDispatch.

 

When a cross apartment call is made COM clears out any error object.

 

Making a COM call that goes through a proxy-stub will clear any existing error object for the calling thread. A called object should not make any such calls after calling SetErrorInfo and before returning. The caller should not make any such calls after the call returns and before calling GetErrorInfo. As a rule of thumb, an interface method should return as soon as possible after calling SetErrorInfo, and the caller should call GetErrorInfo as soon as possible after the call returns.

 

Entering the COM modal message loop will clear any existing error object. A called object should not enter a message loop after calling SetErrorInfo.

 

 

DECLARE FUNCTION SetErrorInfo _

  LIB "OLEAUT32.DLL" _

  ALIAS "SetErrorInfo" ( _

  BYVAL dwReserved AS DWORD _

, BYVAL pperrinfo AS DWORD _

) AS LONG

 

Sample code

 

LOCAL hr AS LONG

LOCAL pcerrinfo AS DWORD

LOCAL perrinfo AS DWORD

 

hr = CreateErrorInfo(pcerrinfo)

IF SUCCEEDED(hr) THEN

   hr = IUnknown_QueryInterface(pcerrinfo, IID_IErrorInfo, perrinfo)

   IF SUCCEEDED(hr) THEN

      SetErrorInfo 0, perrinfo

      IUnknown_Release perrinfo

   END IF

   IUnknown_Release pcerrinfo

END IF

 

 

 

Type Building API Functions

 

CreateTypeLib

 

Provides access to a new object instance that supports the ICreateTypeLib interface.

 

 

DECLARE FUNCTION CreateTypeLib _

  LIB "OLEAUT32.DLL" _

  ALIAS "CreateTypeLib" ( _

  BYVAL syskind AS LONG _

, BYVAL szFile AS STRING _

, BYREF ppctlib AS DWORD _

) AS LONG

 

CreateTypeLib2

 

The CreateTypeLib2 API creates a type library in the current file format. The file and in-memory format for this current version of Automation makes use of memory-mapped files for 32-bit (and files for the Apple Macintosh). The existing CreateTypeLib() API is still available for creating a type library in the older format.

 

 

DECLARE FUNCTION CreateTypeLib2 _

  LIB "OLEAUT32.DLL" _

  ALIAS "CreateTypeLib2" ( _

  BYVAL syskind AS LONG _

, BYVAL szFile AS STRING _

, BYREF ppctlib AS DWORD _

) AS LONG

 

 

 

Support Functions for User-Defined Data Types

 

GetRecordInfoFromTypeInfo

 

Returns a pointer to the IRecordInfo interface of the UDT by passing its type information. The given ITypeInfo interface is used to create a RecordInfo object.

 

 

DECLARE FUNCTION GetRecordInfoFromTypeInfo _

  LIB "OLEAUT32.DLL" _

  ALIAS "GetRecordInfoFromTypeInfo" ( _

  BYVAL pTypeInfo AS DWORD _

, BYREF ppRecInfo AS DWORD _

) AS LONG

 

GetRecordInfoFromGuids

 

Returns a pointer to the IRecordInfo interface for a UDT by passing the GUID of the type information without having to load the type library.

 

A pointer to IRecordInfo can be serialized by writing out the GUIDs and version numbers and deserialized by loading the information and passing it to GetRecordInfoFromGuids.

 

 

DECLARE FUNCTION GetRecordInfoFromGuids _

  LIB "OLEAUT32.DLL" _

  ALIAS "GetRecordInfoFromGuids" ( _

  BYREF rGuidTypeLib AS GUID _

, BYVAL uVerMajor AS DWORD _

, BYVAL uVerMinor AS DWORD _

, BYVAL lcid AS LONG _

, BYREF rGuidTypeInfo AS GUID _

, BYREF ppRecInfo AS DWORD _

) AS LONG

 

 

 

API Level Formating Routines

 

To format a variant into a string you must first tokenize the format string and then apply the format on that string. The API level formatting functions can be used to apply the format in one step and to apply the same format repeatedly. For example, you can call the VarFormat function to apply the formatting at once. If you are going to apply the same format over again you can call VarTokenizeFormatString and use the tokens from VarFormatFromTokens repeatedly. The following table describes the API level formatting routines:

 

 

 

VarTokenizeFormatString

 

Parses the actual format string into a series of tokens which can be used to format variants using VarFormatFromTokens.

 

Parsing the format string once and then using it repeatedly is usually faster than calling VarFormat repeatedly since the latter routines calls VarTokenizeFormatString for each call.

 

The locale you pass in controls how the format string is interpreted, not how the actual output of VarFormatFromTokens will look.

 

 

DECLARE FUNCTION VarTokenizeFormatString _

  LIB "OLEAUT32.DLL" _

  ALIAS "VarTokenizeFormatString" ( _

  BYVAL pstrFormat AS STRING _

, BYVAL rgbTok AS BYTE PTR _

, BYVAL cbTok AS LONG _

, BYVAL iFirstDat AS LONG _

, BYVAL iFirstWeek AS LONG _

, BYVAL lcid AS DWORD _

, BYREF pcbActual AS LONG _

) AS LONG

 

 

VarFormat

 

Formats a variant into string form by parsing a format string.

 

This and the following functions uses the user's default locale while calling VarTokenizeFormatString and VarFormatFromTokens.

 

 

DECLARE FUNCTION VarFormat _

  LIB "OLEAUT32.DLL" _

  ALIAS "VarFormat" ( _

  BYREF pvarIn AS ANY _

, BYVAL pstrFormat AS STRING _

, BYVAL iFirstDay AS LONG _

, BYVAL iFirstWeek AS LONG _

, BYVAL dwFlags AS DWORD _

, BYREF pbstrOut AS STRING _

) AS LONG

 

 

VarFormatDateTime

 

Formats a variant containing named date and time information into a string.

 

 

DECLARE FUNCTION VarFormatDateTime _

  LIB "OLEAUT32.DLL" _

  ALIAS "VarFormatDateTime" ( _

  BYREF pvarIn AS ANY _

, BYVAL iNamedFormat AS LONG _

, BYVAL dwFlags AS DWORD _

, BYREF pbstrOut AS STRING _

) AS LONG

 

 

VarFormatNumber

 

Formats a variant containing numbers into a string form.

 

 

DECLARE FUNCTION VarFormatNumber _

  LIB "OLEAUT32.DLL" _

  ALIAS "VarFormatNumber" ( _

  BYREF pvarIn AS ANY _

, BYVAL iNumDig AS LONG _

, BYVAL ilncLead AS LONG _

, BYVAL iUseParens AS LONG _

, BYVAL iGroup AS LONG _

, BYVAL dwFlags AS DWORD _

, BYREF pbstrOut AS STRING _

) AS LONG

 

 

VarFormatPercent

 

Formats a variant containing percentages into a string form.

 

 

DECLARE FUNCTION VarFormatPercent _

  LIB "OLEAUT32.DLL" _

  ALIAS "VarFormatPercent" ( _

  BYREF pvarIn AS ANY _

, BYVAL iNumDig AS LONG _

, BYVAL ilncLead AS LONG _

, BYVAL iUseParens AS LONG _

, BYVAL iGroup AS LONG _

, BYVAL dwFlags AS DWORD _

, BYREF pbstrOut AS STRING _

) AS LONG

 

 

VarFormatCurrency

 

Formats a variant containing currency values into a string form.

 

 

DECLARE FUNCTION VarFormatCurrency _

  LIB "OLEAUT32.DLL" _

  ALIAS "VarFormatCurrency" ( _

  BYREF pvarIn AS ANY _

, BYVAL iNumDig AS LONG _

, BYVAL ilncLead AS LONG _

, BYVAL iUseParens AS LONG _

, BYVAL iGroup AS LONG _

, BYVAL dwFlags AS DWORD _

, BYREF pbstrOut AS STRING _

) AS LONG

 

 

VarWeekDayName

 

Returns a string containing the localized name of the weekday.

 

 

DECLARE FUNCTION VarWeekdayName _

  LIB "OLEAUT32.DLL" _

  ALIAS "VarWeekdayName" ( _

  BYVAL iWeekday AS LONG _

, BYVAL fAbbrey AS LONG _

, BYVAL iFirstDay AS LONG _

, BYVAL dwFLags AS DWORD _

, BYREF pbstrOut AS STRING _

) AS LONG

 

 

VarFormatFromTokens

 

Takes the output of VarTokenizeFormatString as a format and applies it to a variant to produce a formatted output string.

 

 

DECLARE FUNCTION VarFormatFromTokens _

  LIB "OLEAUT32.DLL" _

  ALIAS "VarFormatFromTokens" ( _

  BYREF pvarIn AS ANY _

, BYVAL pstrFormat AS STRING _

, BYVAL pbTokCur AS BYTE PTR _

, BYVAL dwFlags AS DWORD _

, BYREF pbstrOut AS STRING _

, BYVAL lcid AS DWORD _

) AS LONG

 

 

Page last updated on Wednesday, 30 August 2006 07:12:01 +0200