tags:

views:

496

answers:

3

How can I do to pass a function by parameter, later to be called in VB6? would be something like what I need, can be any of these options:

Private Sub Command1_Click()

    Call callMethod(MyPrivateFunction)
    Call callMethod(MyPublicFunction)
    Call callMethod(MyPrivateSub)
    Call callMethod(MyPublicSub)

End Sub

Private Function MyPrivateFunction()
    MsgBox "MyPrivateFunction"
End Function

Public Function MyPublicFunction()
    MsgBox "MyPublicFunction"
End Function

Private Sub MyPrivateSub()
    MsgBox "MyPrivateSub"
End Sub

Public Sub MyPublicSub()
    MsgBox "MyPublicSub"
End Sub

Public Function callMethod(ByRef func As Object)
    Call func
End Function
+4  A: 

IIRC there is an "AddressOf" function in VB6 to get function addresses, but you will likely have great difficulty actually using that function address from within VB6.

The SOP way to handle this is with "CallByName()" which allows yuo to, you know, call functions, etc. by their names.

finally, you can also take the high road, by using the standard OO solution to this: Instead of passing the function, write your own class that implements a special interface of your own design "MyFunctionInterface". This interface has only one method "FunctionToCall(..)", which you can implement in different classes to call the different functions that you need. Then you pass an instance of one of these classes to your routine, that recieves it as "MyFunctonInterface" and calls the "FunctionToCall" method on it. Of course that takes a whole lot of minor design changes...

RBarryYoung
Ok, given that I will choose another structure, because I need other solution, thanks
andres descalzo
+1  A: 

Your comment that you are using Microsoft.XMLHTTP OnReadyStateChange is interesting. The MSDN page for OnReadyStateChange says it "is designed for use in scripting environments and is not readily accessible in Microsoft® Visual Basic®".

The same page says that in Visual Basic 6 you should do this. Put this variable declaration at module level

 Dim WithEvents xmldoc As DOMDocument30

and then you will be able to handle the event in the usual way like this.

 Private Sub xmldoc_onreadystatechange()
   ' Deal with the event here '
 End Sub

As an aside there's more discussion on calling functions by name in this question. But I think it's the wrong solution for your problem.

MarkJ
thanks, all 3 answers helped me a lot to decide what decision to make.
andres descalzo
+2  A: 

You can't pass a function, but you can pass an object that behaves as a function (called a "functor" sometimes). I use this all the time. If you "functor" class Implements an interface, the call will be type safe. For example:

Abstract class (Interface) IAction.cls:

Option Explicit

Public Sub Create(ByVal vInitArgs As Variant)

End Sub

Public Function exe() As Variant

End Function

Functor that displays a url in the default browser:

Option Explicit

Implements IAction
Dim m_sUrl As String

Public Sub IAction_Create(ByVal vInitArgs As Variant)
        m_sUrl = vInitArgs    
End Sub

Public Function IAction_exe() As Variant


       Call RunUrl(m_sUrl) 'this function is defined elsewhere  

Exit Function

You can now create a bunch of these classes, save them in a collection, pass them to any function or method that expects an IAction, etc...

Fernando
thanks, all 3 answers helped me a lot to decide what decision to make.
andres descalzo