Plantage dans une fonction callback
Bonjour tout le monde.
Une fois n'est pas coutume, je vais publier du code : tenez-vous bien !
Je développe un projet dans lequel j'espère simuler des actions utilisateur dans une autre application. Je lance cette application depuis mon programme, donc je récupère son PID à partir duquel j'obtiens le handle de sa fenêtre principale, puis j'essaie de lister ses fenêtres filles. C'est là que ça plante. Voici le code significatif :
Voire ligne 82
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| Option Explicit
Public Type Fille
Numero As Integer
Handle As Long
Type As String * 20
Texte As String * 20
Autre As String * 20
End Type
Public Filles() As Fille, MaxFilles As Integer, nfille As Long
Public PID As Long, hwnd0 As Long
Public Nom As String
Public IniM As New Ini
Private Declare Function GetWindowThreadProcessId Lib "USER32" (ByVal hwnd As Long, _
lpdwprocessid As Long) As Long
Private Declare Function GetParent Lib "USER32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindow Lib "USER32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Public Declare Function GetWindowText Lib "USER32" Alias "GetWindowTextA" (ByVal hwnd As Long, _
ByVal Texte As String, ByVal L As Long) As Long
Private Declare Function EnumChildWindows Lib "USER32" (ByVal hwnd As Long, ByVal lpEnumProc As Long, _
ByVal LParam As Long) As Boolean
Private Declare Function FindWindow Lib "USER32" Alias "FindWindowA" _
(ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long
Private Declare Function GetClassName Lib "USER32" _
(hwnd As Long, ByRef Nom, longueur As Integer) As Integer
Private Const GW_HWNDNEXT = 2
Public Function ProcIDFromWnd(ByVal hwnd As Long) As Long
'Renvoie l'id d'un processus à partir d'un handle de fenêtre
Dim idproc As Long
GetWindowThreadProcessId hwnd, idproc
ProcIDFromWnd = idproc
End Function
Public Function GetWindowHandle(id As Long) As Long
'Renvoie un handle de fenêtre à partir d'un id de processus
Dim tempHwnd As Long
Nom = "Démineur" & Chr(0)
GetWindowHandle = 0
tempHwnd = FindWindow(vbEmpty, Nom)
Do Until tempHwnd = 0
If GetParent(tempHwnd) = 0 Then
If id = ProcIDFromWnd(tempHwnd) Then
GetWindowHandle = tempHwnd
Exit Do
End If
End If
tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT)
Loop
End Function
Public Sub Fenetres_filles(Mere As Long, fenetre As Object)
'fenetre est la msflexgrid où sont listées les fenêtres filles
Dim i As Integer
MaxFilles = 100
ReDim Filles(MaxFilles)
nfille = 0
Do
If Not EnumChildWindows(Mere, AddressOf Une_Fille, nfille) Then Exit Do
nfille = nfille + 1
Loop
With fenetre
.Rows = nfille + 1
For i = 0 To nfille
.Row = i + 1
.Col = 0
.Text = Format(Filles(i).Numero)
.Col = 1
.Text = Hex(Filles(i).Handle)
.Col = 2
.Text = Filles(i).Texte
Next
End With
End Sub
Public Sub Une_Fille(hwnd As Long, num As Long)
Dim Texte As String * 21, n As Long
If num > MaxFilles Then '<------------------------ ICI ----------------------
MaxFilles = MaxFilles + 100
ReDim Preserve Filles(MaxFilles)
End If
With Filles(num)
.Numero = num
.Handle = hwnd
n = GetClassName(hwnd, Texte, 20)
.Type = Left(Texte, n)
.Texte = ""
.Autre = ""
End With
End Sub |
Après quelques bidouilles, j'appelle Fenetres_filles avec le handle de la mère et la référence de la MSFlexGrid où je veux lister les filles, et c'est là que ça plante.
Si je met un point d'arrêt sur la première instruction de "Une_fille" (je l'ai mise en gras), j'obtiens bien un arrêt là, mais quoi que je fasse ensuite, je sors de VB6 ("quoi que je fasse", c'est par exemple de passer la souris sur "num" pour faire afficher sa valeur, ou F8 pour passer à l'instruction suivante etc...).
Je pense que la cause est évidente : un mauvais pointeur quelque part. Mais où ?
A vot'bon cœur, m'sieurs-dames.
AMIcalement.