How to Write a Visual Basic XCALL

Writing a Visual Basic XCALL is a little more complex than automating A-Shell, but not much. As with automating A-Shell, the first step is to make sure the A-Shell application is registered on the machine on which the Visual Basic code is to be developed. This occurs as a natural part of the A-Shell installation, but can be explicitly performed by executing the following at the command prompt:

ASHW32 –regserver

This step will create entries in the registry which detail the ProgIDs, ClassIDs, and properties and methods of all A-Shell classes.

A Visual Basic XCALL is written as a Visual Basic Public Class, which must be located in an ActiveX DLL project type. Once the project is created then, as with automating A-Shell, the next step is to make sure a reference to A-Shell is created within the project. This can be achieved by choosing ‘Project, References’ from the Visual Basic menu, and then ensuring the following is selected:

A-Shell x.y Object Library (x.y represents the A-Shell Version)

In order to enable a Class module to act as a Visual Basic XCALL, the class must implement the IXcall interface, with the following line:

Implements ASHW32Lib.IXcall

On this interface, the two functions Ping, and Execute must be coded. These will have declarations similar to the following:

Private Function IXcall_Ping(_
        ByVal XcallBlock As ASHW32Lib.IXcallBlock) As Boolean
  …
End Function

And:

Private Sub IXcall_Execute( _
        ByVal XcallBlock As ASHW32Lib.IXcallBlock, _
        ByVal ArgCount As Integer)   
    …
End Sub

When a Visual Basic XCALL is first called from within Alpha BASIC, the Ping function is called. If this returns True, then the early bound reference to the class is cached within A-Shell, and the Execute method then called. If the call to Ping returns False, the AlphaBASIC ‘?Subroutine not found’ error (Basic Error #12) is raised.

The purpose of the Ping function is to allow the XCALL to perform dependency checks, licensing checks, and to determine if the version of A-Shell calling it supports all the interface methods and properties which are needed. The A-Shell interfaces and methods are not set in stone, but will be extended as additional features are brought on line. This version checking is needed to ensure compatibility of the XCALL routine. A typical Ping implementation might read:

Private Function IXcall_Ping(_
        ByVal XcallBlock As ASHW32Lib.IXcallBlock) As Boolean
    '
    Const MIN_EDIT = "490"              ' Minimum edit
    Const MIN_VERSION = "4.7(490)"      ' Minimum edit version
    '
    If XcallBlock.Application.Version(jbvtVSub) >= MIN_EDIT Then
        IXcall_Ping = True
    Else
        IXcall_Ping = False
        MsgBox "JBXcall.ADO requires A-Shell version " & _
               MIN_VERSION & " or later", _
               vbCritical + vbOKOnly, _
               "JBXcall.ADO A-Shell Extension"
    End If
    '
End Function

Following the initial Ping call, the Execute method is called each time the XCALL routine is called.

The final missing piece of the puzzle is how to tell A-Shell about the XCALL, and assign it a traditional XCALL name. This is achieved with the ‘ALIAS=’ line in the A-Shell initialization file MIAME.INI, using entries with the following syntax::

ALIAS={XCALL name}:{XCALL ProgID}

As an example, consider the two subroutines MESAG, and ADO, which are defined in the sample code project – JBXcall. These are enabled for use in A-Shell with the following lines:

ALIAS=MESAG:JBXcall.Mesag
ALIAS=ADO:JBXcall.ADO

XCALL subroutines from multiple DLLs or projects can be referenced in MIAME.INI and used by A-Shell. Conversely, an ActiveX DLL can contain code for any number of XCALLS by containing multiple classes each of which implement the IXcall interface. Only those XCALLs which are actually used need to be referenced in MIAME.INI.