Return value of COM methods and properties.
Err.HResult
An HRESULT is defined in COM as a result handle that can be used for determining the success of failure of a function. However, rather than a handle the HRESULT returns a 32-bits error value. The HRESULT value of properties and methods is examined by GFA-BASIC 32 and in case of failure GFA-BASIC 32 generates an error. GFA-BASIC 32 stores the COM (automation) error in the HResult property of the Err object.
The errors are mostly between $80040000 and $8004FFFF, but not always. Even for automation objects that don't confirm to MS convention (MS Word), GFA-BASIC 32 sets the high word to $8004 to provide a way to identify object errors and normal GFA-BASIC 32 errors. In addition, in case of an OLE-error, the GFA-BASIC 32 documentation says, that the Number property is set to 46 (= Error with object). This might be true (?) for errors with late-binding objects (Object data type), but certainly not with the GFA-BASIC 32 Ocx objects, as we will see.
When an error trap (Try/Catch or On Error GoTo) wants to differentiate between the a BASIC error and a COM error, the best way to go is by checking for a non-null value in HResult.
If Err.HResult Then OLE-error Else GFA-BASIC 32 - error
The HRESULT value can be used to determine the cause of the COM error. The lower word (16-bits) describes what actually took place, error or otherwise. Bits 15 to 30 indicate to which group of status codes the HRESULT value belongs, the so called facility codes. Actually, the facility codes range from 0 to 10 and can be obtained by reading the second byte using GetByte1(). See Remarks for a list of facility codes.
The following example invokes the Node method CreateDragImage, which isn't implemented so far. The returned HRESULT value is examined by GFA-BASIC 32 and an error is generated and trapped. Both, HResult and Number, contain the value E_NOTIMPL ($80004001). The Description property returns a user-readable message for the HRESULT, localized to the user's language as appropriate.
Dim node As Node, p As Picture
Ocx TreeView tv = "", 250, 10, 230, 200
tv.Add , , , "Painters"
Set node = tv.Add(1, tvwChild, "David" , "David")
' invoke a non-implemented method
Try
Set p = node.CreateDragImage
Catch
Debug.Show
Debug Hex(Err.HResult)
Debug Hex(Err), Err.Description
Debug "Facility code: ";GetByte1(Err.HResult)
EndCatch
The Try statement resets the Err object to default values (0 and "").
Note - Actually, the missing CreateDragImage method doesn't generate an error itself like a BASIC error or exception is generated. The method of the Node object is available and the program actually gets inside the CreateDragImage function. However, the COM method immediately returns with E_NOTIMPL, which becomes the HRESULT return value for the method. It is up to the client of CreateDragImage how to handle the return value. By default, GFA-BASIC 32 generates an error. After each call of a property or method GFA-BASIC 32 inserts code to check the return value (HRESULT). If it is not S_OK (0) the Err object is filled and the program comes to a halt. This behavior can be disabled by putting $ObjNoErr into the code.
The following table lists the values of common HRESULT values. (These constants are not implemented in GFA-BASIC 32.)
Name | Value | Description |
---|---|---|
S_OK | 0x00000000 | Operation successful |
E_UNEXPECTED | 0x8000FFFF | Unexpected failure |
E_NOTIMPL | 0x80004001 | Not implemented |
E_OUTOFMEMORY | 0x8007000E | Failed to allocate necessary memory |
E_INVALIDARG | 0x80070057 | One or more arguments are invalid |
E_NOINTERFACE | 0x80004002 | No such interface supported |
E_POINTER | 0x80004003 | Invalid pointer |
E_HANDLE | 0x80070006 | Invalid handle |
E_ABORT | 0x80004004 | Operation aborted |
E_FAIL | 0x80004005 | Unspecified failure |
E_ACCESSDENIED | 0x80070005 | General access denied error |
E_NOTIMPL | 0x80000001 | Not implemented |
The following table describes the various facility fields:
FACILITY_NULL (0) - For broadly applicable common status codes such as S_OK.
FACILITY_RPC (1) - For status codes returned from remote procedure calls.
FACILITY_DISPATCH (2) - For late-binding IDispatch interface errors.
FACILITY_STORAGE (3) - For status codes returned from IStorage or IStream method calls relating to structured storage. Status codes whose code (lower 16 bits) value is in the range of DOS error codes (that is, less than 256) have the same meaning as the corresponding DOS error.
FACILITY_ITF (4) - Most commonly specified code, returned from interface methods, value is defined by the interface.
FACILITY_WIN32 (7) - Used to provide a means of handling error codes from functions in the Win32 API as an HRESULT.
FACILITY_WINDOWS (8) - Used for additional error codes from Microsoft-defined interfaces.
FACILITY_CONTROL (10) - Result related to OLE controls.
Note that a number of HRESULT codes are related to Win32 API functions, because the facility code is 7.
If GetByte1(Err.HResult) = 10 ' an Ocx related error
For more information on COM see the MS SDK.
Err Object
{Created by Sjouke Hamstra; Last updated: 09/10/2014 by James Gaite}