When I saw the possibilities that bring you the CallByName method, I start to work how to adapt its funcionality to my applications. But I found some problems with his four parameter, the arguments.
I tried to pass to this method the list of the parameters of the property or method that I wanted to invoke, but I needed to convert all the values of the Args(). I wanted to pass a list of variants to this parameter, but the method returned an error of types. For exemple, if I wanted to invoke the "Move" method of a form, I need to do:
CallByName Form1, "Move", vbMethod, 1000, 1000, 1000, 1000
and NOT
Dim vals As Variant
ReDim vals(3)
vals(0) = 1000
vals(1) = 1000
vals(2) = 1000
vals(3) = 1000
CallByName Form1, "Move", vbMethod, vals
Luckyly, I find a library that solved me this problem, the TypeLib Information Library. This is a library defined in the tlbinf32.dll file. You can use it making a reference to this library. Next I show a code that resolved many problems to me. I hope it can bring you some aid, too!!
'/ Include this code into a class module
'/ Call the class "CInvoke"
'/
'/ Note: This code need a reference to the
'/ TypeLib Information Library (TLBINF32.DLL)!!
'/
Private TLIApp As New TLIApplication
Private TLInfo As TLI.InterfaceInfo
'/
'/ GetMember
'/ =========
'/ Inputs
'/
'/ - MetProp: The method or property that we want to search in
'/ the Members collection of the object QueriedObject
'/
'/ Output
'/
'/ - Return the member that contain the information of the property/method
'/ we are looking for
'/
Private Property Get GetMember(ByVal MetProp As String) As MemberInfo
Dim i As Long
Set GetMember = Nothing
For i = 1 To TLInfo.Members.Count
If TLInfo.Members(i).Name = MetProp Then
Set GetMember = TLInfo.Members(i)
Exit Property
End If
Next i
End Property
'/
'/ ParamsTransform
'/ ===============
'/ Inputs
'/
'/ - vals: An array that that contains the parameters of the method or property
'/ - args: The array of the parameters that we need to make the invocation (passed by reference)
'/
'/ Output
'/
'/ - Return True if UBound(vals)>-1, or False if the vals array is empty
'/
'/ Note: This method pass a Variant type to a Variant() type, because this is the type
'/ that we need to pass to the method that makes the invocation (InvokeHook...)
'/
Private Function ParamsTransform(ByVal vals As Variant, ByRef args() As Variant) As Boolean
Dim i As Long
ParamsTransform = False
On Error GoTo fin
ReDim args(UBound(vals))
For i = 0 To UBound(vals)
args(i) = vals(i)
Next i
ParamsTransform = True
fin:
End Function
'/
'/ Execute
'/ =======
'/ Inputs
'/
'/ - QueriedObject: The object which we want to make the invocation
'/ - MetProp: The method or property that we want to invocate
'/ - vals: An array that that contains the parameters of the method or property
'/ - res: The value, if any, that returns the invocation (passed by reference)
'/
'/ Output
'/
'/ - Return True if everything has gone ok, or False if exists a problem
'/
Public Function Execute(ByVal QueriedObject As Object, _
ByVal MetProp As String, Optional ByRef vals As Variant, _
Optional ByRef res As Variant) As Boolean
Dim InvokeType As InvokeKinds
Dim Member As MemberInfo
Dim nParams As Long
Dim RetType As Long
Dim args() As Variant
Execute = False
Set TLInfo = TLIApp.InterfaceInfoFromObject(QueriedObject)
Set Member = GetMember(MetProp)
If TypeName(Member) = "Nothing" Then
MsgBox "Error: The name of the property or method doen't exists!"
Exit Function
End If
InvokeType = Member.InvokeKind
RetType = Member.ReturnType.VarType
nParams = -1
If ParamsTransform(vals, args) Then
nParams = UBound(args)
End If
On Error GoTo Handler
Select Case RetType
'/ If RetType = 24 the method don't return any value (void)
Case 24
If nParams = -1 Then
TLIApp.InvokeHookSub QueriedObject, MetProp, InvokeType
Else
TLIApp.InvokeHookArraySub QueriedObject, MetProp, InvokeType, args
End If
'/ If RetType = 0 Or 9, the method or property return an Object, so
'/ we need to use the "Set" sentencia to instance the res
'/ variable as an object
Case 0, 9
If nParams = -1 Then
Set res = TLIApp.InvokeHook(QueriedObject, MetProp, InvokeType)
Else
Set res = TLIApp.InvokeHookArray(QueriedObject, MetProp, InvokeType, args)
End If
'/ In other case, the method or property return a non object value
Case Else
If nParams = -1 Then
res = TLIApp.InvokeHook(QueriedObject, MetProp, InvokeType)
Else
res = TLIApp.InvokeHookArray(QueriedObject, MetProp, InvokeType, args)
End If
End Select
Execute = True
Exit Function
Handler:
'/ If there is an error...
MsgBox (Err.Number - vbObjectError) & vbCrLf & Err.Source & _
vbCrLf & Err.Description
End Function
'/ Now, you can use this class in your forms
'/ Add this code into a form with a CommandButton (Command1) and a TextBox (Text1)
Private oc As New CInvoke
Private Sub Command1_Click()
Dim vals As Variant
ReDim vals(0)
vals(0) = Text1.Text
oc.Execute Me, "Move", vals
End Sub
Private Sub Form_Load()
Me.Text1.Text = CStr(Me.Left)
End Sub
Cheers!!
![[pipe] [pipe] [pipe]](/data/assets/smilies/pipe.gif)
![[peace] [peace] [peace]](/data/assets/smilies/peace.gif)
I tried to pass to this method the list of the parameters of the property or method that I wanted to invoke, but I needed to convert all the values of the Args(). I wanted to pass a list of variants to this parameter, but the method returned an error of types. For exemple, if I wanted to invoke the "Move" method of a form, I need to do:
CallByName Form1, "Move", vbMethod, 1000, 1000, 1000, 1000
and NOT
Dim vals As Variant
ReDim vals(3)
vals(0) = 1000
vals(1) = 1000
vals(2) = 1000
vals(3) = 1000
CallByName Form1, "Move", vbMethod, vals
Luckyly, I find a library that solved me this problem, the TypeLib Information Library. This is a library defined in the tlbinf32.dll file. You can use it making a reference to this library. Next I show a code that resolved many problems to me. I hope it can bring you some aid, too!!
'/ Include this code into a class module
'/ Call the class "CInvoke"
'/
'/ Note: This code need a reference to the
'/ TypeLib Information Library (TLBINF32.DLL)!!
'/
Private TLIApp As New TLIApplication
Private TLInfo As TLI.InterfaceInfo
'/
'/ GetMember
'/ =========
'/ Inputs
'/
'/ - MetProp: The method or property that we want to search in
'/ the Members collection of the object QueriedObject
'/
'/ Output
'/
'/ - Return the member that contain the information of the property/method
'/ we are looking for
'/
Private Property Get GetMember(ByVal MetProp As String) As MemberInfo
Dim i As Long
Set GetMember = Nothing
For i = 1 To TLInfo.Members.Count
If TLInfo.Members(i).Name = MetProp Then
Set GetMember = TLInfo.Members(i)
Exit Property
End If
Next i
End Property
'/
'/ ParamsTransform
'/ ===============
'/ Inputs
'/
'/ - vals: An array that that contains the parameters of the method or property
'/ - args: The array of the parameters that we need to make the invocation (passed by reference)
'/
'/ Output
'/
'/ - Return True if UBound(vals)>-1, or False if the vals array is empty
'/
'/ Note: This method pass a Variant type to a Variant() type, because this is the type
'/ that we need to pass to the method that makes the invocation (InvokeHook...)
'/
Private Function ParamsTransform(ByVal vals As Variant, ByRef args() As Variant) As Boolean
Dim i As Long
ParamsTransform = False
On Error GoTo fin
ReDim args(UBound(vals))
For i = 0 To UBound(vals)
args(i) = vals(i)
Next i
ParamsTransform = True
fin:
End Function
'/
'/ Execute
'/ =======
'/ Inputs
'/
'/ - QueriedObject: The object which we want to make the invocation
'/ - MetProp: The method or property that we want to invocate
'/ - vals: An array that that contains the parameters of the method or property
'/ - res: The value, if any, that returns the invocation (passed by reference)
'/
'/ Output
'/
'/ - Return True if everything has gone ok, or False if exists a problem
'/
Public Function Execute(ByVal QueriedObject As Object, _
ByVal MetProp As String, Optional ByRef vals As Variant, _
Optional ByRef res As Variant) As Boolean
Dim InvokeType As InvokeKinds
Dim Member As MemberInfo
Dim nParams As Long
Dim RetType As Long
Dim args() As Variant
Execute = False
Set TLInfo = TLIApp.InterfaceInfoFromObject(QueriedObject)
Set Member = GetMember(MetProp)
If TypeName(Member) = "Nothing" Then
MsgBox "Error: The name of the property or method doen't exists!"
Exit Function
End If
InvokeType = Member.InvokeKind
RetType = Member.ReturnType.VarType
nParams = -1
If ParamsTransform(vals, args) Then
nParams = UBound(args)
End If
On Error GoTo Handler
Select Case RetType
'/ If RetType = 24 the method don't return any value (void)
Case 24
If nParams = -1 Then
TLIApp.InvokeHookSub QueriedObject, MetProp, InvokeType
Else
TLIApp.InvokeHookArraySub QueriedObject, MetProp, InvokeType, args
End If
'/ If RetType = 0 Or 9, the method or property return an Object, so
'/ we need to use the "Set" sentencia to instance the res
'/ variable as an object
Case 0, 9
If nParams = -1 Then
Set res = TLIApp.InvokeHook(QueriedObject, MetProp, InvokeType)
Else
Set res = TLIApp.InvokeHookArray(QueriedObject, MetProp, InvokeType, args)
End If
'/ In other case, the method or property return a non object value
Case Else
If nParams = -1 Then
res = TLIApp.InvokeHook(QueriedObject, MetProp, InvokeType)
Else
res = TLIApp.InvokeHookArray(QueriedObject, MetProp, InvokeType, args)
End If
End Select
Execute = True
Exit Function
Handler:
'/ If there is an error...
MsgBox (Err.Number - vbObjectError) & vbCrLf & Err.Source & _
vbCrLf & Err.Description
End Function
'/ Now, you can use this class in your forms
'/ Add this code into a form with a CommandButton (Command1) and a TextBox (Text1)
Private oc As New CInvoke
Private Sub Command1_Click()
Dim vals As Variant
ReDim vals(0)
vals(0) = Text1.Text
oc.Execute Me, "Move", vals
End Sub
Private Sub Form_Load()
Me.Text1.Text = CStr(Me.Left)
End Sub
Cheers!!
![[pipe] [pipe] [pipe]](/data/assets/smilies/pipe.gif)
![[peace] [peace] [peace]](/data/assets/smilies/peace.gif)