OLE Automation 1994 Technical Notes

This release of OLE Automation contains several enhancements and corrections that are not documented in the online Help file. The following 
changes will be included in the next version of the OLE 2 Programmer's Reference, Volume 2.

	Returning Error Information
	Retrieving Error Information
	Errror Handling Interfaces

	ICreateErrorInfo Interface
	IErrorInfo Interface
	ISupportErrorInfo Interface

	Error Handling Functions
	Registering Interfaces
	New ODL Attributes
	Type Library Loading Function
	LoadTypeLibFromResource
	ArrayManipulation Functions

	SafeArrayPtrOfIndex

	DEFINE_GUID macros
	Additions to ITypeInfo Structures and Enumerations

	Active Object Registration

	National Language Support

####
Error Handling

When an OLE Automation client application calls an OLE vtable interface that returns an HRESULT, it is now possible for an OLE Automation 
client to get the same rich (contextual) information that is returned from IDispatch::Invoke.

Objects that are invoked through vtables need to use the OLE Automation error handling interfaces to define and return error information. The 
interfaces and functions include the following:

	ICreateErrorInfo interface  Sets error information.
	IErrorInfo interface  Returns information from an error object.
	ISupportErrorInfo interface  Identifies this object as supporting the ErrorInfo interface.
	Error handling functions  Create, retrieve, set and clear the error object. 



The member functions of each interface are listed in the following table. 

Category	Member name	Purpose
IErrorInfo	GetDescription	Returns a textual description of the error.
	GetGUID	Returns the GUID for the interface that defined the error.
	GetHelpContext	Returns the Help context ID for the error.
	GetHelpFile	Returns the path of the Help file that describes the error.
	GetSource	Returns the ProgID for the class or application that returned the error.
ICreateErrorInfo	SetDescription	Sets a textual description of the error.
	SetGUID	Sets the GUID for the interface that defined the error.
	SetHelpContext	Sets the Help context ID for the error.
	SetHelpFile	Sets the path of the Help file that describes the error.
	SetSource	Sets the ProgID for the class or application that returned the error.
ISupportErrorInfo	InterfaceSupportsErrorInfo	Indicates whether an interface supports the IErrorInfo interface.
Error handling functions	CreateErrorInfo	Creates a generic error object.
	GetErrorInfo	Retrieves and clears the current error object.
	SetErrorInfo	Sets the current error object.


####
Returning Error Information

The error handling interfaces create and manage an error object, which provides information about the error. The error object is not the same as 
the object that encountered the error; it is a separate object that is associated with the current thread of execution. 

	To return error information

	1.	Implement the ISupportErrorInfo interface.
	2.	Call the CreateErrorInfo function to create an instance of a generic error object.
	3.	Use the ICreateErrorInfo methods to set its contents.
	4.	Call the SetErrorInfo function to associate the error object with the current logical thread.



####
Retrieving Error Information

	To retrieve error information, an object

	1.	Checks whether the returned SCODE represents an error that the object is prepared to handle.
	2.	Calls QueryInterface on the object (ISupportErrorInfo::InterfaceSupportsErrorInfo) to verify that the object that returned the error code 
supports the ErrorInfo interface. If ErrorInfo is not supported, additional information about the error is not available.
	3.	Calls the GetErrorInfo function to get a pointer to the error object.
	4.	Uses the IErrorInfo methods to retrieve information from the error object.



If the object cannot  handle the error, but needs to propagate the error information further down the call chain, it should pass the SCODE to its 
caller. Because the GetErrorInfo function clears the error information, the function should be called only by the object that handles the error.

####
ICreateErrorInfo Interface

Implemented by	Used by	Header filename
OLEAUT32.DLLOLE2DISP.DLL	Applications that return rich error information	OLEAUTO.H DISPATCH.H


The functions included in this section are:
ICreateErrorInfo::SetDescription
ICreateErrorInfo::SetGUID
ICreateErrorInfo::SetHelpContext
ICreateErrorInfo::SetHelpFile
ICreateErrorInfo::SetSource 

####
ICreateErrorInfo::SetDescription

HRESULT ICreateErrorInfo::SetDescription(szDescription)
LPOLESTR * szDescription

Sets the textual description of the error.

Parameters

szDescription

A brief, zero-terminated string that describes the error.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success


Comments

The text should be supplied in the language specified by the LCID that was passed to the method that raised the error. Refer to the section on 
lcid parameters for more information.

####
ICreateErrorInfo::SetGUID

HRESULT ICreateErrorInfo::SetGUID(rguid) 
REFGUID rguid

Sets the GUID of interface that defined the error.

Parameters

rguid

The GUID of the interface that defined the error, or GUID_NULL, if the error was defined by the operating system.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success


Comments

ICreateErrorInfo::SetGUID sets the GUID of the interface that defined the error. If the error was defined by the system, 
ICreateErrorInfo::SetGUID should set GUID_NULL.   
This GUID does not necessarily represent the source of the error. The source is the class or application that raised the error.  Using the GUID, 
applications can handle errors in an interface independent of the class that implements the interface.

####ICreateErrorInfo::SetHelpContext

HRESULT ICreateErrorInfo::SetHelpContext(dwHelpContext) 
DWORD dwHelpContext

Sets the Help context ID for the error.

Parameters

dwHelpContext

The Help context ID for the error.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success


Comments

ICreateErrorInfo::SetHelpContext sets the Help context ID for the error.  To establish the Help file to which it applies, use 
ICreateErrorInfo::SetHelpFile.

####
ICreateErrorInfo::SetHelpFile

HRESULT ICreateErrorInfo::SetHelpFile(szHelpFile)
LPOLESTR szHelpFile

Sets the path of the Help file that describes the error.

Parameters

szHelpFile

The fully qualified path of the Help file that describes the error.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success


Comments

ICreateErrorInfo::SetHelpFile sets the fully qualified path of the Help file that describes the current error. Use 
ICreateErrorInfo::SetHelpContext to set the Help context ID for the error within the Help file.

####
ICreateErrorInfo::SetSource

HRESULT ICreateErrorInfo::SetSource(szSource)
LPSTR szSource

Sets the language-dependent ProgID for the class or application that raised the error.

Parameters

szSource

A programmatic ID, in the form progname.objectname. 



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success


Comments

Use ICreateErrorInfo::SetSource to identify the class or application that is the source of the error.  The language for the returned ProgID 
depends on the LCID that was passed into the method at invocation.

####
IErrorInfo Interface

Implemented by	Used by	Header filename
OLEAUT32.DLLOLE2DISP.DLL	Applications that receive rich information	OLEAUTO.HDISPATCH.H


Functions included in this section are:
IErrorInfo::GetDescription
IErrorInfo::GetGUID
IErrorInfo::GetHelpContext
IErrorInfo::GetHelpFile
IErrorInfo::GetSource 

####
IErrorInfo::GetDescription	

HRESULT IErrorInfo::GetDescription(pbstrDescription)
BSTR * pbstrDescription

Returns a textual description of the error.

Parameters

pbstrDescription

Pointer to where to return a brief string that describes the error.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success



Comments

The text is returned in the language specified by the LCID that was passed to IDispatch::Invoke for the method that encountered the error.

####
IErrorInfo::GetGUID

HRESULT IErrorInfo::GetGUID(pguid)
GUID * pguid

Returns the GUID of interface that defined the error.

Parameters

pguid

Pointer to a GUID, or GUID_NULL, if the error was defined by the operating system.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success


Comments

IErrorInfo::GetGUID returns the GUID of the interface that defined the error. If the error was defined by the system, IError::GetGUID returns 
GUID_NULL.    
Note that this GUID does not necessarily represent the source of the error, however; the source is the class or application that raised the error.  
Using the GUID, your application can handle errors in an interface independent of the class that implements the interface.

####
IErrorInfo::GetHelpContext

HRESULT IErrorInfo::GetHelpContext(pdwHelpContext)
DWORD * pdwHelpContext

Returns the Help context ID for the error.

Parameters

pdwHelpContext

Pointer to the Help context ID for the error.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success


Comments

IErrorInfo::GetHelpContext returns the Help context ID for the error.  To find the Help file to which it applies, use IErrorInfo::GetHelpFile.

####
IErrorInfo::GetHelpFile

HRESULT IErrorInfo::GetHelpFile(pbstrHelpFile)
BSTR * pbstrHelpFile

Returns the path of the Help file that describes the error.

Parameters

pbstrHelpFile

Pointer to a string containing the fully qualified path of the Help file.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success


Comments

IErrorInfo::GetHelpFile returns the fully qualified path of the Help file that describes the current error. Use IError::GetHelpContext to find the 
Help context ID for the error within the Help file.

####
IErrorInfo::GetSource

HRESULT IErrorInfo::GetSource(pbstrSource)
BSTR * pbstrSource

Returns the language-dependent ProgID for the class or application that raised the error.

Parameters

pbstrSource

Pointer to a string containing a ProgID.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success


Comments

Use IErrorInfo::GetSource to determine the class or application that is the source of the error.  The language for the returned ProgID depends 
on the LCID that was passed into the method at invocation.

####
ISupportErrorInfo Interface

Implemented by	Used by	Header filename
Applications that return error information	Applications that retrieve error information	OLEAUTO.H


The function included in this interface is:
ISupportErrorInfo::InterfaceSupportsErrorInfo 

####
ISupportErrorInfo::InterfaceSupportsErrorInfo

HRESULT ISupportErrorInfo::InterfaceSupportsErrorInfo(riid)
REFIID riid

Indicates whether an interface supports the IErrorInfo interface.

Parameters

riid

Pointer to an interface ID.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Interface supports IErrorInfo.
S_FALSE	Interface does not support IErrorInfo.


Comments

Objects that support IErrorInfo must implement this interface.
Objects that receive an error SCODE should call QueryInterface to get a pointer to the ISupportErrorInfo interface, then call 
InterfaceSupportsErrorInfo with the riid of the interface that returned the SCODE. If InterfaceSupportsErrorInfo returns S_FALSE, then the 
error object does not represent an error returned from the caller, but from somewhere further up the call chain.  In this case, the error object can 
be considered incorrect and should be discarded. 
If InterfaceSupportsErrorInfo returns S_OK, use GetErrorInfo to get a pointer to the error object.

####
Error Handling Functions

Implemented by	Used by	Header filename
OLEAUT32.DLLOLE2DISP.DLL	Applications that receive rich error information	OLEAUTO.HDISPATCH.H


The functions included in this interface are:
CreateErrorInfo
GetErrorInfo
SetErrorInfo 

####
CreateErrorInfo

HRESULT CreateErrorInfo(ppcerrinfo) 
ICreateErrorInfo * *  ppcerrinfo

Creates an instance of a generic error object.

Parameters

ppcerrinfo

Pointer to a system-implemented generic error object.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success
E_OUTOFMEMORY	Could not create the error object.


Comments

This function returns a pointer to a generic error object, which can later be passed to ICreateErrorInfo or SetErrorInfo to set the error 
information for the current logical thread.  The generic error object implements both ICreateErrorInfo and IErrorInfo.  

####
GetErrorInfo

HRESULT GetErrorInfo(DWORD dwReserved,  
IErrorInfo * *  pperrinfo)

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

Parameters

pperrinfo

Pointer to a pointer to an error object.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success
S_FALSE 	There was no error object to return.


Comments

This function returns a pointer to the most recently set IErrorInfo pointer in the current logical thread, and removes the error object from the 
thread; in effect, it clears the error object.  Use this function only in code that will handle the error.  Code that needs to propagate the error should 
simply pass along the error SCODE without retrieving the error object.

####
SetErrorInfo

HRESULT SetErrorInfo(DWORD dwReserved,  
IErrorInfo * *  pperrinfo)

Sets the error information pointer for the current thread of execution.

Parameters

perrinfo

Pointer to an error object.  



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK 	Success


Comments

This function releases the existing error information pointer and sets the pointer to perrinfo. Use this function after creating an error object to 
associate the object with the current thread of execution. 

####
Registering Interfaces

By default, OLE Automation registers dispinterfaces that appear in the ODL file.  It also registers remote OLE Automation-compatible interfaces 
that are not registered elsewhere under the ProxyStubClsid.
Example

The ProxyStubClsid in the following example refers to the proxy/stub implementation of IDispatch.


HKEY_CLASSES_ROOT\Interface\{D3CE6D46-F1AF-1068-9FBB-08002B32372A} = _DHello
HKEY_CLASSES_ROOT\Interface\{D3CE6D46-F1AF-1068-9FBB-08002B32372A}
\ProxyStubClsid = {00020420-0000-0000-C000-000000000046}


####
New ODL Attributes

Type information is described using the Object Description Language (ODL). Scripts written in ODL are compiled with the MkTypLib tool to 
create type libraries. New attributes for this release are described here.

Nonextensible Objects

Compile-time checking is provided to generate "member-not-found" and "parameter type mismatch" for nonextensible objects. The TypeInfo for 
an interface can be set as nonextensible through the nonextensible ODL attribute. If no attribute is specified, the interface is assumed to be 
extensible.

Hidden

The hidden attribute is used to indicate that a given member or interface should not be displayed in a browser, but that the member should 
still exist, and the macro programmer should be able to bind to it.

[hidden]
dispinterface Document
{
  [hidden] void PrintOut
  void Print
}

Control

The control attribute indicates that the item represents a control from which a container site will derive additional type libraries or component 
classes. This attribute allows you to mark type libraries that describe controls so that they will not be displayed in type browsers intended for 
nonvisual objects. The TypeInfo of the container should describe the members of the controls and the TypeInfo of the control members should 
be used. 

 [control]
CoClass ListBox
{
  [Default] DListBox
}

Source (on a Property or Method)

The source attribute now also indicates that a property or method returns an object that is a source of events. The property or method must 
return a VARIANT or object. By using the source attribute for controls, you can attach code to these pieces of the whole object using 
IConnectionPointContainer.

OLE Automation Compatibility

The oleautomation attribute indicates that an interface is compatible with OLE Automation. The parameters and return types specified for its 
members must be OLE Automation-compatible, as listed in the following table.

Type	Description
int	Signed integer, whose size is system-dependent.
boolean	Data item that can have the values True or False. The size may be system-dependent.
char	8-bit signed data item.
double	64-bit IEEE floating-point number.
float	32-bit IEEE floating-point number.
long	32-bit signed integer.
short	16-bit signed integer.
BSTR	Length-prefixed string.
typedef enum myenum	Signed integer, whose size is system-dependent.
CURRENCY	8-byte fixed-point number.
DATE	64-bit floating-point fractional number of days since December 30, 1899.
IDispatch *	Pointer to IDispatch interface (VT_DISPATCH).
IUnknown *	Pointer to interface that does not derive from IDispatch (VT_UNKNOWN). (Any OLE interface can be represented by its IUnknown interface.)
Typename *	Where Typename is a coclass, dispinterface, or another OLE Automation-compatible interface.


The following are compatibility rules:

	A parameter is compatible with OLE Automation if its type is an OLE Automation- compatible type, a pointer to an OLE 
Automation-compatible type, or a SafeArray of an OLE Automation-compatible type.  
	A return type is compatible with OLE Automation if its type is either an HRESULT or is an OLE Automation-compatible type.  
	A member is compatible with OLE Automation if its return type and all of its parameters are compatible with OLE Automation. 
	An interface is compatible with OLE Automation if it derives from IDispatch, if it has the oleautomation or dual attribute, and if all of its 
vtable entries are OLE Automation compatible.  
	Every dispinterface is OLE Automation compatible.



Dual Interfaces

The dual attribute creates an interface that is both a Dispatch interface and a Component Object Model interface. The first seven entries of the 
vtable for a dual interface are the seven members of IDispatch, and the remaining entries are OLE Component Object Model entries for direct 
access to members of the interface. All the parameters and return types specified for members of a dual interface must be OLE 
Automation-compatible types.
Dual interfaces provide for both the speed of direct vtable binding and the flexibility of IDispatch binding. For this reason, dual interfaces are 
recommended whenever possible.

Raising Exceptions

Members of interfaces that need to raise exceptions should return an HRESULT and specify a retval parameter for the actual return value. The 
retval parameter is always the last parameter in the list. 
The following example creates a dual interface, which supports both vtable and IDispatch binding to its members.

[dual] interface Goodbye : IDispatch
{
	// A property that is a string
	[propget] HRESULT GoodbyeMessage ()
		[out, retval] BSTR * pbstrRetVal);
	[propput] HRESULT GoodbyeMessage ([in] BSTR rhs);
	
	//A method that takes a long integer and returns a string
	HRESULT SayGoodbye([in] long NextTime,
					   [out, retval] BSTR *pbstrRetVal);
}


TypeInfo and Dual Interfaces

Dual interfaces have two different TypeInfos for the same interface. The TKIND_INTERFACE TypeInfo describes the interface as a standard 
OLE Component Object Model interface. The TKIND_DISPATCH TypeInfo describes the interface as a standard Dispatch interface. The lcid 
and retval parameters and HRESULT return types are removed, and the return type of the member is specified to be the same type as the 
retval parameter. 
By default, the TypeKind for a dual interface is TKIND_DISPATCH. Tools that bind to interfaces should check the type flags for 
TYPEFLAG_FDUAL. If this flag is set, the TKIND_INTERFACE TypeInfo is available through a call to ITypeInfo::GetRefTypeOfImplType.

Using the lcid Attribute

When ITypeInfo::Invoke calls an object's vtable, it passes the LCID of the TypeInfo into parameters tagged with the lcid attribute, and gets 
the return value from the retval parameter.
If the member returns an error scode, it uses the Error Interfaces to get rich error information and fill in the ExceptInfo structure that it returns, 
and returns DISP_E_EXCEPTION.
The following example defines an interface named IMyInt, which has a pair of accessor functions for the MyMessage property and a method 
that returns a string.

interface IMyInt : IUnknown
{
	//A property that is a string
	[propget] HRESULT MyMessage([in, lcid] LCID lcid,
								[out, retval] BSTR *pbstrRetVal);
	[propput] HRESULT MyMessage([in] BSTR rhs, [in, lcid] DWORD lcid);
	
	//A method returning a string
	HRESULT SayMessage([in] long NumTimes,
					   [in, lcid] DWORD lcid,
					   [out, retval] BSTR *pbstrRetVal);
}


The members of this interface return error information and function return values through the HRESULT values and retval parameters, 
respectively. Tools that access the members can return the HRESULT, or can expose the retval parameter as the return value and handle the 
HRESULT transparently.

New ODL Attribute Descriptions

MkTypeLib accepts the following new attributes.

Attribute	Allowed on	Comments
control	Typelib and coclass	Indicates that the item represents a control from which a container site will derive additional typelibs or coclasses. This attribute allows you to mark type libraries that describe controls so that they will not be displayed in type browsers intended for nonvisual objects. Representation: TYPEFLAG_FCONTROL, LIBFLAG_FCONTROL
dual	Interface	Identifies an interface that can be bound with IDispatch and directly through the vtable. The interface must be compatible with OLE Automation and derive from IDispatch. Not allowed on dispinterfaces.Specifying dual on an interface implies that the interface is compatible with OLE Automation, and therefore causes both the TYPEFLAG_FDUAL and TYPEFLAG_FOLEAUTOMATION flags to be set.Representation: LIBFLAG FDUAL, FUNCFLAG, TYPEFLAG_FDUAL and TYPEFLAG_FOLEAUTOMATION
hidden	Property, method, coclass, dispinterface, and typelib	Indicates that the item exists but should not be displayed in a user-oriented browser. This attribute allows you to remove members from your interface (by shielding them from further use) while maintaining compatibility with existing code.Representation: VARFLAG_FHIDDEN, FUNCFLAG_FHIDDEN, TYPEFLAG_FHIDDEN, LIBFLAG FHIDDEN
lcid	parameter	Indicates that the parameter is the locale ID. At most one parameter may have this attribute.  The parameter must have the in attribute and can't have the out attribute, and its type must be DWORD. The lcid attribute is not allowed on Dispatch interfaces. By convention, the lcid parameter is the last parameter that does not have the retval attribute.  ITypeInfo::Invoke passes the LCID of the TypeInfo into the lcid parameter. Parameters with this attibute are not displayed in browsers. 
licensed 	Coclass 	Indicates that the class is licensed.Representation: TYPEFLAG_FLICENSED
nonextensible	Dispinterface, interface	Indicates that the IDispatch implementation includes only the properties and methods listed in the interface or dispinterface description. The dispinterface or interface must have the oleautomation attribute.By default, OLE Automation assumes that interfaces may add members at runtime; that is, it assumes they are extensible. Representation: TYPEFLAG_FNONEXTENSIBLE
oleautomation	Interface	Indicates that the interface is compatible with OLE Automation. Not allowed on dispinterfaces.Representation: TYPEFLAG_FOLEAUTOMATION
retval	Parameters of interface members that describe methods or get properties	Indicates that the parameter is the return value of the member.  This attribute may be used only on the last parameter of the member.  The parameter must have the out attribute and must be a pointer type.Parameters with this attibute are not displayed in user-oriented browsers. Representation: IDLFLAG_FRETVAL
source	Property or method	Indicates that the property or method returns an object that is a source of events. The property or method must return a VARIANT or object.   Indicates that the object implements IConnectionPointContainer.Representation:  VARFLAG_SOURCE, FUNCFLAG_SOURCE 


####
Type Loading Function

Multiple type libraries can now be stored in an executable (.EXE) file or DLL. These libraries can be loaded using LoadTypeLibFromResource.


####
LoadTypeLibFromResource

HRESULT LoadTypeLibFromResource(szFileName, szResName, lResID, lplptlib)
OLECHAR FAR* szFileName
OLECHAR FAR* szResName
long  lResID
ITypeLib FAR* FAR* lplptlib

Loads a type library from a designated position in a DLL or .EXE file.

Parameters

szFileName

Contains the name of a DLL or .EXE file that contains a type library in one of its resource areas.

szResName

Identifies the resource area that contains the type library.

lResID

Identifies the resource ID that contains the type library.

lplptlib

On return, contains a pointer to a pointer to the loaded type library.



Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK	Success.
E_OUTOFMEMORY	Out of memory.
E_INVALIDARG	One or more of the arguments is invalid.
TYPE_E_IOERROR	The function could not read the file.
TYPE_E_INVDATAREAD	The function could not read from the file.
TYPE_E_UNSUPFORMAT	The type library has an old format.
TYPE_E_CANTLOADLIBRARY	The type library or DLL could not be loaded.
Other returns	All FACILITY_STORAGE errors may also be returned.


Comments

The DLL or .EXE file may contain more than one type library.  Use LoadTypeLibFromResource to load a type library stored at positions other 
than lResID = 1.  Use LoadTypeLib or LoadRegTypeLib to load the type library that is stored at the standard position, that is, lResID = 1.  
LoadTypeLibFromResource does not register the type library.  After successfully loading the library, you must call RegisterTypeLibrary to 
register the library.
If szFileName specifies only a filename, with no path, LoadTypeLibFromResource will search for the file according to the Path variable. 
If the type library is already loaded, LoadTypeLibFromResource increments the type library's reference count and returns a pointer to the type 
library. 

####
Array Manipulation Functions

The SafeArrayPtrOfIndex function has been added to calculate the address of any given element in a safe array. 

####
SafeArrayPtrOfIndex

HRESULT SafeArrayPtrOfIndex(psa, rgIndices, ppvData)
SAFEARRAY FAR* psa 
long FAR* rgIndices 
void HUGEP* FAR* ppvData	

Returns a pointer to an array element.

Parameters

psa

Pointer to an array descriptor created by SafeArrayCreate.

rgIndices

An array of index values that identify an element of the array.  All indexes for the element must be specified.

ppvData

On return, pointer to the element identified by the values in rgIndices.



Comments

The array should be locked before SafeArrayPtrOfIndex is called.  Failing to lock the array may cause undpredictable results.

Return Value

The SCODE obtained from the returned HRESULT is as follows:

SCODE	Meaning
S_OK	Success.
E_INVALIDARG	The argument psa was not a valid safe array descriptor.
DISP_E_BADINDEX	The specified index was invalid.

####
DEFINE_GUID Macros

MkTypLib creates a type library file (extension .TLB) based on source text input contained in the file specified by ODLfile. It can optionally 
produce a header file (extension .H), which is a stripped version of the input file suitable for inclusion in C or C++ programs that want to access 
the types defined in the input file. When it generates the header file, MkTypLib includes DEFINE_GUID macros for each element (interface, 
dispinterface, and so forth) defined in the type library.

####
ITypeInfo Structures and Enumerations

The following new elements have been added for the new ODL attributes.

TYPEFLAGS
VARFLAGS
FUNCFLAGS

####
TYPEFLAGS

The TYPEFLAGS enumeration is defined as follows:

typedef enum tagTYPEFLAGS {
	TYPEFLAG_FAPPOBJECT = 0x01
    , TYPEFLAG_FCANCREATE = 0x02
    , TYPEFLAG_FLICENSED = 0x04
    , TYPEFLAG_FPREDECLID = 0x08
    , TYPEFLAG_FHIDDEN = 0x10
    , TYPEFLAG_FCONTROL = 0x20
    , TYPEFLAG_FDUAL = 0x40
    , TYPEFLAG_FNONEXTENSIBLE = 0x80
    , TYPEFLAG_FOLEAUTOMATION = 0x100
} TYPEFLAGS;





Value	Description
TYPEFLAG_FAPPOBJECT	A type description that describes an Application object.
TYPEFLAG_FCANCREATE	Instances of the type can be created by ITypeInfo::CreateInstance.
TYPEFLAG_FLICENSED	The type is licensed.
TYPEFLAG_FPREDECLID	The type is predefined. The client application should automatically create a single instance of the object that has this attribute. The name of the variable that points to the object is the same as the class name of the object.
TYPEFLAG_FHIDDEN	The type should not be displayed to browsers.
TYPEFLAG_FCONTROL	The type is a control from which other types will be derived, and should not be displayed to users.
TYPEFLAG_FDUAL	The types in the interface derive from IDispatch and are fully compatible with OLE Automation.  Not allowed on Dispatch interfaces.  
TYPEFLAG_FNONEXTENSIBLE	The interface can't add members at run time.
TYPEFLAG_FOLEAUTOMATION	The types used in the interface are fully compatible with OLE, and may be displayed in an object browser.  Setting [dual] on an interface sets this flag in addition to TYPEFLAG_FDUAL.  Not allowed on Dispatch interfaces.


####
VARFLAGS

The VARFLAGS enumeration is defined as follows:

typedef enum tagVARFLAGS {
      VARFLAG_FREADONLY= 1
      , VARFLAG_FSOURCE= 0x2
      , VARFLAG_FBINDABLE= 0x4
      , VARFLAG_FREQUESTEDIT= 0x8
      , VARFLAG_FDISPLAYBIND= 0x10
      , VARFLAG_FDEFAULTBIND= 0x20
      , VARFLAG_FHIDDEN= 0x40
} VARFLAGS;


Value	Description
VARFLAG_READONLY	Assignment to the variable should not be allowed.
VARFLAG_FSOURCE	The variable returns an object that is a source of events.
VARFLAG_FBINDABLE	The variable supports data binding.
VARFLAG_FDISPLAYBIND	The variable is displayed to the user as bindable; that is, VARFLAG_FBINDABLE must also be set.   
VARFLAG_FDEFAULTBIND	The variable is the single property that best represents the object.  Only one variable in a dispinterface may have this attibute.  
VARFLAG_FHIDDEN	The variable should not be displayed to the user in a browser, though it exists and is bindable.


####
FUNCFLAGS

The FUNCFLAGS enumeration is defined as follows:

typedef enum tagFUNCFLAGS {
	FUNCFLAG_FRESTRICTED= 1
      , FUNCFLAG_FSOURCE= 0x2
      , FUNCFLAG_FBINDABLE= 0x4
      , FUNCFLAG_FREQUESTEDIT= 0x8
      , FUNCFLAG_FDISPLAYBIND= 0x10
      , FUNCFLAG_FDEFAULTBIND= 0x20
      , FUNCFLAG_FHIDDEN= 0x40
} FUNCFLAGS;


Value	Description
FUNCFLAG_FRESTRICTED	The function should not be accessible from macro languages. This flag is intended for system-level functions or functions that you do not want type browsers to display.
FUNCFLAG_FSOURCE	The function returns an object that is a source of events.
FUNCFLAG_FBINDABLE	The function that supports data binding.
FUNCFLAG_FDISPLAYBIND	The function that is displayed to the user as bindable; that is, FUNC_FBINDABLE must also be set.   
FUNCFLAG_FDEFAULTBIND	The function that best represents the object.  Only one function in a dispinterface may have this attibute.  
FUNCFLAG_FHIDDEN	The function should not be displayed to the user, though it exists and is bindable.


####
Active Object Registration

A new flag has been added to the RegisterActiveObject function to specify weak and strong registration. 

####
RegisterActiveObject

HRESULT RegisterActiveObject (punk, rclsid, dwFlags, pdwRegister)
IUnknown FAR* punk
REFCLSID rclsid
unsigned long dwFlags 
unsigned long FAR* pdwRegister

Registers an object (punk) as the active object for the class indicated by rclsid.

Parameters

punk

Pointer to the IUnknown interface of the active object.

rclsid

Pointer to the class ID of the active object.

dwFlags

Flags controlling registration of an object. Possible values are 
ACTIVEOBJECT_STRONG  and ACTIVEOBJECT_WEAK .

pdwRegister

Pointer to a handle used when initializing and revoking an active object. This handle is created by RegisterActiveObject and passed to 
RevokeActiveObject when you want to end an object's status as active.



Return Value

The SCODE obtained from the returned HRESULT is one of the following:

SCODE	Meaning
S_OK	Success
Other returns	Failure


Comments

The RegisterActiveObject function registers the object to which punk points as the active object for the class indicated by rclsid. Registration 
causes the object to be listed in OLE's running object table, a globally accessible lookup table that keeps track of the objects that are 
currently running on the workstation. (See the OLE 2 Programmer's Reference, Volume 1 for more information on the running object table.) The 
dwFlags parameter specifies the strength or weakness of the registration, which affects the way the object is shut down.
In general, OLE Automation objects should behave in the following manner:

	If the object is visible, it should shut down only in response to an explicit user command (such as the Exit command from a File menu), or 
to the equivalent command from the OLE Automation controller (invoking the Quit or Exit method on the Application object). 
	If the object is not visible, it should shut down only when the last external connection to it disappears.



Strong registration performs an AddRef on the object, thereby incrementing the reference count of the object (and its associated stub) in the 
running object table. A strongly registered object must be explicitly revoked from the table with RevokeActiveObject. Strong registration 
(ACTIVEOBJECT_STRONG) is the default.
Weak registration keeps a pointer to the object in the running object table, but does not increment the reference count. Consequently, when 
the last external connection to a weakly registered object disappears, OLE releases the object's stub and the object itself is no longer 
available.
To ensure the desired behavior, you must not only consider OLE's default actions,  but you need to consider the following:

	Even though your code creates an invisible object, the object may become visible at some later time. Once the object is visible, it should 
remain visible and active until it receives an explicit command to shut down, which may occur after references from your code disappear.
	Other OLE Automation controllers may be using the object. If so, your code should not force the object to shut down.



To avoid possible conflicts, OLE Automation objects should always register with ACTIVEOBJECT_WEAK, and call CoLockObjectExternal 
when necessary to guarantee that the object remains active. CoLockObjectExternal adds a strong lock, thereby preventing the object's 
reference count from reaching zero. For detailed information on this function, refer to the OLE 2 Programmer's Reference, Volume 1.
Most commonly, objects need to call CoLockObjectExternal when they become visible, so that they remain active until the user requests a 
shut down. Ensure that your code contains the following steps:

	1.	When the object becomes visible, make the following call to add a lock on behalf of the user:



		CoLockObjectExternal(punk, TRUE, TRUE)


The lock should remain in effect until the user explicitly requests shutdown, such as with a Quit or Exit command.

	2.	When the user requests shutdown, call CoLockObjectExternal again to free the lock, as follows:



		CoLockObjectExternal(punk, FALSE, TRUE)


	3.	Call RevokeActiveObject to make the object inactive.
	4.	To end all connections from remote processes, call CoDisconnectObject as follows:



		CoDisconnectObject(punk, 0)


	This function is described in the OLE 2 Programmer's Reference, Volume 1. 

####
National Language Support

The following LCTYPE constants have been added to OLE Automation for 16-bit systems. All values are variable length ANSI strings, and are 
null-terminated. The values in the brackets indicate a maximum number of characters allowed for the string (including the null termination). If 
no maximum is indicated, then the string may be of variable length. When you request any of this information by using GetLocaleInfo, the 
API returns the appropriate string depending on what the current system ANSI code page is.

Constant name	Description
LOCALE_IFIRSTWEEKOFYEAR	Specifies which week of the year is considered first. [2]"0"	Week containing 1/1 is the first 		week of that year."1"	First full week following 1/1 is the 		first week of that year."2"	First week containing at least 4 		days is the first week of that year.
LOCALE_IFIRSTDAYOFWEEK	Specifies which day is considered first in a week. [2]"0"		SDAYNAME1"1"		SDAYNAME2"2"		SDAYNAME3"3"		SDAYNAME4"4"		SDAYNAME5"5"		SDAYNAME6"6"		SDAYNAME7
LOCALE_IDEFAULTANSICODEPAGE	ANSI code page associated with this locale [6]
LOCALE_INEGNUMBER	Negative number mode. [2]"0"	(1.1)"1"	-1.1"2"	-1.1"3"	1.1"4"	1.1
LOCALE_STIMEFORMAT	Time formatting string. [80]
LOCALE_ITIMEMARKPOSN	Whether the time marker string (AM|PM designator) preceeds or succeeds the time string.  The registry value is name iTimePrefix for previous Far East version compatability."0"	Suffix (that is, 9:15 AM) "1"	Prefix (that is, AM 9:15) 
LOCALE_ICALENDARTYPE	Specifies which type of calendar is currently being used. [2]"1"	Gregorian (as in United States)"2"	Gregorian (always English strings)"3"	Era: Year of the Emperor (Japan)"4"	Era: Year of the Republic of China"5"	Tangun Era (Korea)
LOCALE_IOPTIONALCALENDAR	Specifies which additional calendar types are valid and available for this LCID.  This can be a null-separated list of all valid optional calendars. [2]"0"	No additional types valid"1"	Gregorian (localized) "2"	Gregorian (always English strings)"3"	Era: Year of the Emperor (Japan) "4"	Era: Year of the Republic of China "5"	Tangun Era (Korea)
LOCALE_SMONTHNAME13	Native name for 13th month, if exists.
LOCALE_SABBREVMONTHNAME13	Native abbreviated name for 13th month, if exists.


In this version, every value has a maximum length (in bytes, and including the null-terminator) shown in brackets, at the end of its format 
description. 

####
New Data Type

OLE Automation supports the VT_UI1 data type (VARTYPE). This data type is useful for creating arrays of binary data. You can create a 
VT_ARRAY | VT_UI1 and use it as a binary byte buffer in your code. This guarantees that no ANSI to Unicode translation will be performed on a 
binary buffer on 32-bit systems.



####
