Comment écrire une fonction de rappel dans VB6? Je sais AddressOf vous obtient la fonction obtient l'adresse dans un long. Mais comment appeler la fonction avec l'adresse mémoire? Merci!Comment écrire un callback dans VB6?
Répondre
Je ne sais pas exactement ce que vous essayez de faire.
Pour invert control, créez simplement la fonction de rappel dans une classe. Utilisez ensuite une instance de la classe (un objet) pour effectuer le rappel.
- Si vous avez besoin de basculer entre différentes routines au moment de l'exécution, ayez des classes distinctes qui implémentent la même interface - un strategy pattern.
- IMHO
AddressOf
est beaucoup trop compliqué et risqué à utiliser de cette manière.
AddressOf
devrait ne être utilisé si vous avez besoin register callback functions avec l'API Windows.
J'ai posté mon intention sur le fil de commentaires principal. Mais je vais le republier ici: j'ai une fonction dans un module qui prend plus de quelques cycles. Je pensais à utiliser un rappel de la fonction pour laisser l'appelant savoir que c'est un progrès. Donc, je l'utiliserais presque comme un événement, sauf à partir d'une fonction et non d'une classe. –
Oups, j'ai négligé ces commentaires. Eh bien, ne pourriez-vous pas passer un objet à la fonction, et rappeler dans l'objet? Ou mettre la fonction dans une nouvelle classe, et soulever des événements de la classe? Les deux sont de beaux motifs OO propres. Solutions de contournement pour le manque de délégués dans VB6. – MarkJ
This post sur vbforums.com donne un exemple d'utilisation de AddressOf et de la fonction CallWindowProc pour exécuter une procédure de rappel.
code du poste:
Private Declare Function CallWindowProc _
Lib "user32.dll" Alias "CallWindowProcA" (_
ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, _
ByVal msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Private Sub ShowMessage(_
msg As String, _
ByVal nUnused1 As Long, _
ByVal nUnused2 As Long, _
ByVal nUnused3 As Long)
'This is the Sub we will call by address
'it only use one argument but we need to pull the others
'from the stack, so they are just declared as Long values
MsgBox msg
End Sub
Private Function ProcPtr(ByVal nAddress As Long) As Long
'Just return the address we just got
ProcPtr = nAddress
End Function
Public Sub YouCantDoThisInVB()
Dim sMessage As String
Dim nSubAddress As Long
'This message will be passed to our Sub as an argument
sMessage = InputBox("Please input a short message")
'Get the address to the sub we are going to call
nSubAddress = ProcPtr(AddressOf ShowMessage)
'Do the magic!
CallWindowProc nSubAddress, VarPtr(sMessage), 0&, 0&, 0&
End Sub
Plutôt risqué d'utiliser AddressOf comme ceci. Pourquoi ne pas simplement créer la fonction de rappel dans une classe et utiliser une instance (un objet) pour effectuer le rappel? – MarkJ
... Si vous faites une erreur, votre application entière mourra avec une erreur d'exception non gérée. – MarkJ
@MarkJ: Je suis d'accord. C'est juste un exemple d'un moyen de le faire - pas nécessairement celui que je choisirais. –
Pour quoi avez-vous besoin du rappel? La réponse différera drastiquement en fonction de cela. –
J'ai une fonction dans un module qui prend plus de quelques cycles. Je pensais à utiliser un rappel de la fonction pour laisser l'appelant savoir que c'est un progrès. Donc, je l'utiliserais presque comme un événement, sauf à partir d'une fonction et non d'une classe. –