'Wrapper2: Option Public Option Declare Use "class:ls2capiWrapperClass" '** A wrapper around a wrapper around a wrapper... '** This just simplifies some of the object creation and array building '** we normally have to do. Class simpleApiWrapper As ls2capiWrapperClass Public functionName As String Public params() As ls2capiParameterClass Private paramCount As Integer Public types() As ls2capiTypeClass Private typeCount As Integer Public returnVal As ls2capiParameterClass Public Sub New (functionName As String) Me.functionName = functionName End Sub '** Add a new parameter. You must add parameters in the exact order '** they appear in the function call. A rule of thumb is: if it's a value you're '** sending TO the function, isByVal=True; if it's a value you're getting '** back FROM the function, isByVal=False. Public Function addParam (thisName As String, thisType As Integer, _ isByVal As Integer, thisVal As Variant) As simpleApiWrapper Dim param As New ls2capiParameterClass(thisType, isByVal, _ thisName, thisVal, "") Redim Preserve params(paramCount) Set params(paramCount) = param paramCount = paramCount + 1 Set addParam = Me End Function '** Add a Type parameter. These are a little tricky to create. '** See the OSCurrentTIMEDATE() method in APICalls for an example. Public Function addTypeParam (thisName As String, _ thisType As ls2capiTypeClass) As simpleApiWrapper Redim Preserve types(typeCount) Set types(typeCount) = thisType typeCount = typeCount + 1 Set addTypeParam = addParam(thisName, type_CUSTOM, False, thisType) End Function '** Get a Parameter object based on either it's position in the parameter '** array (from 0 to UBound(params)) or the name you gave it when it was '** created. Public Function getParam (paramNum As Variant) As ls2capiParameterClass ' you can pass a numeric array position or a parameter name here If (Datatype(paramNum) < 8) Then If (paramNum >= 0) And (paramNum < paramCount) Then Set getParam = params(paramNum) End If Else Forall p In params If (p.pName = paramNum) Then Set getParam = p End If End Forall End If End Function '** Get a Parameter value based on either it's position in the parameter '** array (from 0 to UBound(params)) or the name you gave it when it was '** created. Public Function getParamValue (paramNum As Variant) As Variant Dim param As ls2capiParameterClass Set param = Me.getParam(paramNum) If (param Is Nothing) Then getParamValue = -1 Else getParamValue = param.getValue() End If End Function '** Change a Parameter value based on either it's position in the parameter '** array (from 0 to UBound(params)) or the name you gave it when it was '** created. This is useful for making multiple calls to the same function. Public Function setParam (paramNum As Variant, paramValue As Variant) As simpleApiWrapper ' you can pass a numeric array position or a parameter name here Dim pos As Integer, i As Integer If (Datatype(paramNum) < 8) Then pos = Cint(paramNum) Else pos = -1 For i = 0 To paramCount-1 If (params(i).pName = paramNum) Then pos = i End If Next End If If (pos >= 0) And (pos < paramCount) Then Dim p As ls2capiParameterClass Set p = params(pos) Set p = New ls2capiParameterClass(p.pType, p.pByVal, p.pName, _ paramValue, p.pExternalVariableUsed) Set params(pos) = p End If Set setParam = Me End Function '** Set the return value type, if there is one Public Function setReturnType (thisType As Integer) As simpleApiWrapper Set returnVal = New ls2capiParameterClass(thisType, True, "returnVal", 0, "") Set setReturnType = Me End Function '** after a function has been run, get its return value Public Function getReturnValue () As Variant getReturnValue = returnVal.getValue() End Function '** Run the function and cross your fingers. If something goes wrong '** the return value of this method will be False. Or the computer will crash. '** Otherwise it will be whatever the API return value is. If the return value '** is type_STATUS and it's not zero, you can get the error message from '** returnVal.valStatusString Public Function run () As Variant On Error Goto errorhandler Dim A As New ls2capiCallClass(functionName, params, returnVal) If (typeCount > 0) Then Forall t In types Call A.addType(t) End Forall End If ' Now. Scary stuff. Actually call the API. If Me.callAPI(A) Then Me.run = True Else ' Optimistic Basically if the call fails, then the process crashes. Call Me.logErrorMsg("APICallClass::" & functionName & ": Failed to return from the CallAPI function" ) End If exitFunction: Exit Function errorhandler: Call Me.raiseError() Resume exitFunction End Function End Class Sub Initialize '** Let's try OSGetExecutableDirectory Dim apiNotesDir As New simpleApiWrapper("OSGetExecutableDirectory") Call apiNotesDir.addParam("PathName", type_STRING, False, "") Call apiNotesDir.setReturnType(type_WORD) If apiNotesDir.run() Then Print "Exe Path = " & apiNotesDir.getParamValue("PathName") End If '** you can chain calls together too, if you're into that sort of thing Dim apiDataDir As New simpleApiWrapper("OSGetDataDirectory") If apiDataDir.addParam("PathName", type_STRING, False, "").setReturnType(type_WORD).run() Then Print "Data Path = " & apiDataDir.getParamValue("PathName") End If '** ping a server? Dim apiPing As New simpleApiWrapper("NSPingServer") Call apiPing.addParam("ServerName", type_STRING, True, "Oscar") Call apiPing.addParam("AvailabilityIndex", type_DWORD, False, 0) Call apiPing.addParam("NullValue", type_WORD, False, 0) Call apiPing.setReturnType(type_STATUS) If apiPing.run() Then Print "Server Availability for " & apiPing.getParamValue("ServerName") & _ " is " & apiPing.getParamValue("AvailabilityIndex") End If '** change the server name and run it again Call apiPing.setParam("ServerName", "NotAServer") If apiPing.run() Then Print "Server Availability for " & apiPing.getParamValue(0) & _ " is " & apiPing.getParamValue(1) Else Print "Error pinging " & apiPing.getParamValue(0) & _ ": " & apiPing.returnVal.valStatusString End If '** how about SECHashPassword Dim apiHash As New simpleApiWrapper("SECHashPassword") Dim password As String password = "My Super Secret Password" Call apiHash.addParam("PasswordLen", type_WORD, True, Len(password)) Call apiHash.addParam("Password", type_STRING, True, password) Call apiHash.addParam("MaxDigestLen", type_WORD, True, 1024) Call apiHash.addParam("RetDigestLen", type_WORD, False, 0) Call apiHash.addParam("RetDigest", type_STRING, False, "") Call apiHash.addParam("ReservedFlags", type_DWORD, True, 0) Call apiHash.addParam("NullValue", type_WORD, True, 0) Call apiHash.setReturnType(type_STATUS) If apiHash.run() Then Dim digestLength As Integer digestLength = apiHash.getParamValue("RetDigestLen") Print "Return Digest Length = " & digestLength Print "Digest = " & Left(apiHash.getParamValue("RetDigest"), digestLength) '** PROBLEM: '** param.getValue() doesn't work here because getValue() always looks for '** a Chr(0) in the return string, and in this case there is no Chr(0). So we need '** to access the return string directly. Dim p As ls2capiParameterClass Set p = apiHash.getParam("RetDigest") Print "Digest = " & Left(p.valStringBuffer, digestLength) End If End Sub