Je cherche à copier le contenu d'une zone de texte d'une application
extérieure, par exemple vers un fichier texte.
Pour cela, il m'a semblé que SendMessage pouvait être un bon filon,
j'espère ne pas m'être trompé. Alors je commence par faire des exercices.
Je me suis référé à ce qui est fourni avec VB6, à savoir une copie de la
fiche 141073. Pour la trouver dans HTML de VB6, on peut y chercher par
exemple EM_GETLINE, et trouver dans les rubriques "Using Windows API
Functions to Better Manipulate Text Boxes".
Il faut mettre les déclarations au goût du jour :
Private Declare Function GetFocus Lib "user32" () As Long
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Const EM_GETLINECOUNT = &HBA
Private Const EM_GETLINE = &HC4
Private Const EM_LINELENGTH = &HC1
Private Const EM_GETSEL = &HB0
Private Const EM_LINEFROMCHAR = &HC9
Private Const EM_LINEINDEX = &HBB
Private Const EM_SETSEL = &HB1
Private Const EM_REPLACESEL = &HC2
J'ai désactivé la deuxième instruction de Form_Load,
X% = fReplaceSel("")
le motif en est indiqué par le commentaire.
ça démarrait bien, et puis l'application s'est plantée, et VB6 avec.
J'ai tout remis en place, et il s'avère que le plantage se produit dans
fGetLine, au niveau de SendMessage
Un peu plus haut, ça n'a pas suffi d'agrandir un peu le buffer, de 2
octets, ni ensuite de le doubler :
Buffer = Chr$(byteLo%) + Chr$(byteHi%) _
+ Space$(2 * MAX_CHAR_PER_LINE) ' exit - 2)
- 2 ou pas - 2, doublé ou pas doublé la taille du buffer, même motif
même punition, VB manque de mémoire, alors il se suicide.
Ah oui histoire d'être clair, manque de mémoire, ça s'appelle erreur 7.
Gloops a écrit, le 22/06/2005 02:45 :
- 2 ou pas - 2, doublé ou pas doublé la taille du buffer, même motif même punition, VB manque de mémoire, alors il se suicide.
Qui saura le dissuader de franchir le parapet ?
Zoury
Salut Gloops ! :O)
Si tu déclare LParam "Byref .. As Any", tu dois employé ByVal lorsque tu passes le buffer à SendMessage.
Ex : '*** Option Explicit
Private Declare Function SendMessage _ Lib "user32" _ Alias "SendMessageA" ( _ ByVal hWnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByRef lParam As Any) As Long
Si tu déclare LParam "Byref .. As Any", tu dois employé ByVal lorsque tu
passes le buffer à SendMessage.
Ex :
'***
Option Explicit
Private Declare Function SendMessage _
Lib "user32" _
Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByRef lParam As Any) As Long
Si tu déclare LParam "Byref .. As Any", tu dois employé ByVal lorsque tu passes le buffer à SendMessage.
Ex : '*** Option Explicit
Private Declare Function SendMessage _ Lib "user32" _ Alias "SendMessageA" ( _ ByVal hWnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByRef lParam As Any) As Long
Ah, quand il y a ByRef dans la déclaration, il faut employer ByVal dans l'appel ...
Ben mon gars, heureusement que tu es là pour me le dire.
ça doit pourtant être écrit quelque part dans le Platinium, mais apparemment à une page que je n'ai pas lue.
Merci, je vais essayer ça ce soir. ____________________________________ Zoury a écrit, le 22/06/2005 17:43 :
Salut Gloops ! :O)
Si tu déclare LParam "Byref .. As Any", tu dois employé ByVal lorsque tu passes le buffer à SendMessage.
Ex : '*** Option Explicit
Private Declare Function SendMessage _ Lib "user32" _ Alias "SendMessageA" ( _ ByVal hWnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByRef lParam As Any) As Long
Ah, quand il y a ByRef dans la déclaration, il faut employer ByVal dans
l'appel ...
Ben mon gars, heureusement que tu es là pour me le dire.
ça doit pourtant être écrit quelque part dans le Platinium, mais
apparemment à une page que je n'ai pas lue.
Merci, je vais essayer ça ce soir.
____________________________________
Zoury a écrit, le 22/06/2005 17:43 :
Salut Gloops ! :O)
Si tu déclare LParam "Byref .. As Any", tu dois employé ByVal lorsque tu
passes le buffer à SendMessage.
Ex :
'***
Option Explicit
Private Declare Function SendMessage _
Lib "user32" _
Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByRef lParam As Any) As Long
Ah, quand il y a ByRef dans la déclaration, il faut employer ByVal dans l'appel ...
Ben mon gars, heureusement que tu es là pour me le dire.
ça doit pourtant être écrit quelque part dans le Platinium, mais apparemment à une page que je n'ai pas lue.
Merci, je vais essayer ça ce soir. ____________________________________ Zoury a écrit, le 22/06/2005 17:43 :
Salut Gloops ! :O)
Si tu déclare LParam "Byref .. As Any", tu dois employé ByVal lorsque tu passes le buffer à SendMessage.
Ex : '*** Option Explicit
Private Declare Function SendMessage _ Lib "user32" _ Alias "SendMessageA" ( _ ByVal hWnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByRef lParam As Any) As Long
En fait, il faut savoir que tu veux passer un pointeur vers une chaine (Byval) et pas un pointeur vers un pointeur vers une chaine (Byref). Tout cela est expliqué plus en détail dans le livre blanc à ce sujet: http://www.microsoft.com/downloads/details.aspx?familyidÎ7DA635-78A1-457E-9959-C3996CF25C03&displaylang=fr
-- Picalausa François "Gloops" a écrit dans le message de news: 42b9a59f$0$1237$
Ah, quand il y a ByRef dans la déclaration, il faut employer ByVal dans l'appel ...
Ben mon gars, heureusement que tu es là pour me le dire.
ça doit pourtant être écrit quelque part dans le Platinium, mais apparemment à une page que je n'ai pas lue.
Merci, je vais essayer ça ce soir. ____________________________________ Zoury a écrit, le 22/06/2005 17:43 :
Salut Gloops ! :O)
Si tu déclare LParam "Byref .. As Any", tu dois employé ByVal lorsque tu passes le buffer à SendMessage.
Ex : '*** Option Explicit
Private Declare Function SendMessage _ Lib "user32" _ Alias "SendMessageA" ( _ ByVal hWnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByRef lParam As Any) As Long
En fait, il faut savoir que tu veux passer un pointeur vers une chaine
(Byval) et pas un pointeur vers un pointeur vers une chaine (Byref).
Tout cela est expliqué plus en détail dans le livre blanc à ce sujet:
http://www.microsoft.com/downloads/details.aspx?familyidÎ7DA635-78A1-457E-9959-C3996CF25C03&displaylang=fr
--
Picalausa François
"Gloops" <gloops@niark.fr> a écrit dans le message de news:
42b9a59f$0$1237$8fcfb975@news.wanadoo.fr...
Ah, quand il y a ByRef dans la déclaration, il faut employer ByVal dans
l'appel ...
Ben mon gars, heureusement que tu es là pour me le dire.
ça doit pourtant être écrit quelque part dans le Platinium, mais
apparemment à une page que je n'ai pas lue.
Merci, je vais essayer ça ce soir.
____________________________________
Zoury a écrit, le 22/06/2005 17:43 :
Salut Gloops ! :O)
Si tu déclare LParam "Byref .. As Any", tu dois employé ByVal lorsque tu
passes le buffer à SendMessage.
Ex :
'***
Option Explicit
Private Declare Function SendMessage _
Lib "user32" _
Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByRef lParam As Any) As Long
En fait, il faut savoir que tu veux passer un pointeur vers une chaine (Byval) et pas un pointeur vers un pointeur vers une chaine (Byref). Tout cela est expliqué plus en détail dans le livre blanc à ce sujet: http://www.microsoft.com/downloads/details.aspx?familyidÎ7DA635-78A1-457E-9959-C3996CF25C03&displaylang=fr
-- Picalausa François "Gloops" a écrit dans le message de news: 42b9a59f$0$1237$
Ah, quand il y a ByRef dans la déclaration, il faut employer ByVal dans l'appel ...
Ben mon gars, heureusement que tu es là pour me le dire.
ça doit pourtant être écrit quelque part dans le Platinium, mais apparemment à une page que je n'ai pas lue.
Merci, je vais essayer ça ce soir. ____________________________________ Zoury a écrit, le 22/06/2005 17:43 :
Salut Gloops ! :O)
Si tu déclare LParam "Byref .. As Any", tu dois employé ByVal lorsque tu passes le buffer à SendMessage.
Ex : '*** Option Explicit
Private Declare Function SendMessage _ Lib "user32" _ Alias "SendMessageA" ( _ ByVal hWnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByRef lParam As Any) As Long
Ah pardon, j'ai compris depuis, c'est "As Any" qui implique de passer le paramètre "By Val", un peu comme si, quand on promettait de raser gratis, ça ne valait que si on précisait dans quelle monnaie, vu que pour l'API la déclaration ne dit pas quel type de donnée la fonction est en mesure de modifier, donc si on lui passe autre chose que ce avec quoi elle a été conçue pour travailler, c'est logique, ça coince.
Je dois dire que quand je suis rentré cet après-midi je n'étais pas frais, c'est peu de le dire.
ça fait que maintenant, tout marche, y compris l'affichage du texte de la ligne, merci.
La fiche met la taille du tampon dans les deux premiers octets, comme on fait en C si je me rappelle bien. Ce n'est pas précisé par la doc, est-ce juste une habitude, ou est-ce qu'on risque aussi des ennuis si on ne le fait pas ?
En attaquant ça je me suis dit que j'allais pouvoir recueillir les données reçues par minitel avec l'hyperterminal, mais ça n'est peut-être pas aussi simple que ça. On n'est pas guidé par les titres des contrôles. Si j'en juge par le numéro retourné par WindowFromPoint avec le curseur sur la zone visée, on devrait pouvoir attaquer le dernier enfant de la fenêtre principale de l'hyperterminal (sur quatre si je me rappelle bien, les autres étant organisés en hiérarchie sur ces quatre), mais SendMessage WM_GETTEXT ne retourne rien là-dessus, pas plus que EM_GETLINECOUNT, EM_GETHANDLE, EM_LINELENGTH (après avoir bien sûr pris soin de recevoir des données). Ou alors il y a plusieurs fenêtres superposées, et WindowFromPoint ne peut retourner qu'un numéro. Il va peut-être falloir que j'affiche toute la hiérarchie, avec les coordonnées et quand c'est possible le texte ...
Ou alors ce n'est pas une zone de texte ? C'est vrai qu'il y a des gras et des italiques, à afficher ... Il faudra que je regarde si on a des messages prévus pour une RichText, avec SendMessage.
Bon, avant tout je vais lire la doc proposée par François ...
Ah pardon, j'ai compris depuis, c'est "As Any" qui implique de passer le
paramètre "By Val", un peu comme si, quand on promettait de raser
gratis, ça ne valait que si on précisait dans quelle monnaie, vu que
pour l'API la déclaration ne dit pas quel type de donnée la fonction est
en mesure de modifier, donc si on lui passe autre chose que ce avec quoi
elle a été conçue pour travailler, c'est logique, ça coince.
Je dois dire que quand je suis rentré cet après-midi je n'étais pas
frais, c'est peu de le dire.
ça fait que maintenant, tout marche, y compris l'affichage du texte de
la ligne, merci.
La fiche met la taille du tampon dans les deux premiers octets, comme on
fait en C si je me rappelle bien. Ce n'est pas précisé par la doc,
est-ce juste une habitude, ou est-ce qu'on risque aussi des ennuis si on
ne le fait pas ?
En attaquant ça je me suis dit que j'allais pouvoir recueillir les
données reçues par minitel avec l'hyperterminal, mais ça n'est peut-être
pas aussi simple que ça. On n'est pas guidé par les titres des
contrôles. Si j'en juge par le numéro retourné par WindowFromPoint avec
le curseur sur la zone visée, on devrait pouvoir attaquer le dernier
enfant de la fenêtre principale de l'hyperterminal (sur quatre si je me
rappelle bien, les autres étant organisés en hiérarchie sur ces quatre),
mais SendMessage WM_GETTEXT ne retourne rien là-dessus, pas plus que
EM_GETLINECOUNT, EM_GETHANDLE, EM_LINELENGTH (après avoir bien sûr pris
soin de recevoir des données). Ou alors il y a plusieurs fenêtres
superposées, et WindowFromPoint ne peut retourner qu'un numéro. Il va
peut-être falloir que j'affiche toute la hiérarchie, avec les
coordonnées et quand c'est possible le texte ...
Ou alors ce n'est pas une zone de texte ? C'est vrai qu'il y a des gras
et des italiques, à afficher ... Il faudra que je regarde si on a des
messages prévus pour une RichText, avec SendMessage.
Bon, avant tout je vais lire la doc proposée par François ...
Ah pardon, j'ai compris depuis, c'est "As Any" qui implique de passer le paramètre "By Val", un peu comme si, quand on promettait de raser gratis, ça ne valait que si on précisait dans quelle monnaie, vu que pour l'API la déclaration ne dit pas quel type de donnée la fonction est en mesure de modifier, donc si on lui passe autre chose que ce avec quoi elle a été conçue pour travailler, c'est logique, ça coince.
Je dois dire que quand je suis rentré cet après-midi je n'étais pas frais, c'est peu de le dire.
ça fait que maintenant, tout marche, y compris l'affichage du texte de la ligne, merci.
La fiche met la taille du tampon dans les deux premiers octets, comme on fait en C si je me rappelle bien. Ce n'est pas précisé par la doc, est-ce juste une habitude, ou est-ce qu'on risque aussi des ennuis si on ne le fait pas ?
En attaquant ça je me suis dit que j'allais pouvoir recueillir les données reçues par minitel avec l'hyperterminal, mais ça n'est peut-être pas aussi simple que ça. On n'est pas guidé par les titres des contrôles. Si j'en juge par le numéro retourné par WindowFromPoint avec le curseur sur la zone visée, on devrait pouvoir attaquer le dernier enfant de la fenêtre principale de l'hyperterminal (sur quatre si je me rappelle bien, les autres étant organisés en hiérarchie sur ces quatre), mais SendMessage WM_GETTEXT ne retourne rien là-dessus, pas plus que EM_GETLINECOUNT, EM_GETHANDLE, EM_LINELENGTH (après avoir bien sûr pris soin de recevoir des données). Ou alors il y a plusieurs fenêtres superposées, et WindowFromPoint ne peut retourner qu'un numéro. Il va peut-être falloir que j'affiche toute la hiérarchie, avec les coordonnées et quand c'est possible le texte ...
Ou alors ce n'est pas une zone de texte ? C'est vrai qu'il y a des gras et des italiques, à afficher ... Il faudra que je regarde si on a des messages prévus pour une RichText, avec SendMessage.
Bon, avant tout je vais lire la doc proposée par François ...
Gloops
Bonjour,
Ah ben au moins je n'ai pas posé ma question pour rien. Je vais regarder ça tranquillement demain, merci. _________________________________________________ Picalausa François a écrit, le 22/06/2005 20:03 :
Hello,
En fait, il faut savoir que tu veux passer un pointeur vers une chaine (Byval) et pas un pointeur vers un pointeur vers une chaine (Byref). Tout cela est expliqué plus en détail dans le livre blanc à ce sujet: http://www.microsoft.com/downloads/details.aspx?familyidÎ7DA635-78A1-457E-9959-C3996CF25C03&displaylang=fr
Bonjour,
Ah ben au moins je n'ai pas posé ma question pour rien.
Je vais regarder ça tranquillement demain, merci.
_________________________________________________
Picalausa François a écrit, le 22/06/2005 20:03 :
Hello,
En fait, il faut savoir que tu veux passer un pointeur vers une chaine
(Byval) et pas un pointeur vers un pointeur vers une chaine (Byref).
Tout cela est expliqué plus en détail dans le livre blanc à ce sujet:
http://www.microsoft.com/downloads/details.aspx?familyidÎ7DA635-78A1-457E-9959-C3996CF25C03&displaylang=fr
Ah ben au moins je n'ai pas posé ma question pour rien. Je vais regarder ça tranquillement demain, merci. _________________________________________________ Picalausa François a écrit, le 22/06/2005 20:03 :
Hello,
En fait, il faut savoir que tu veux passer un pointeur vers une chaine (Byval) et pas un pointeur vers un pointeur vers une chaine (Byref). Tout cela est expliqué plus en détail dans le livre blanc à ce sujet: http://www.microsoft.com/downloads/details.aspx?familyidÎ7DA635-78A1-457E-9959-C3996CF25C03&displaylang=fr
Intéressant. Je crois que j'ai loupé les shémas en lisant ça dans Word 95, en rentrant à la maison je chercherai la visionneuse.
J'ai repris les exemples des pages 8 et 9, et je n'ai pas eu exactement les mêmes résultats, peut-être quelque chose m'a-t-il échappé.
================= Début ===================== Private Declare Sub CopyMemory Lib "kernel32" _ Alias "RtlMoveMemory" _ (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Dim maChaine As String
Public Sub maProc() Dim monTab(19) As Byte Dim i As Integer
For i = 0 To 19 Debug.Print i, monTab(i), Chr$(monTab(i)) Next
End Sub ================= Fin ======================= Résultat : Form1.maProc Len(maChaine) = 4 0 65 A 1 73 I 2 68 D 3 69 E 4 0 5 0 6 106 j 7 0 8 0 et le reste à 0.
J'ai un caractère aléatoire en position 6, si je fais plusieurs appels successifs ce caractère ne sera pas forcément le même. Les quatre premiers caractères, en revanche, sont bien ceux qu'on a voulu passer.
Si maintenant, en longueur, au lieu de LenB(maChaine), je mets len(maChaine), je passe juste les caractères, et j'obtiens
0 65 A 1 73 I 2 68 D 3 69 E 4 0 5 0 6 0 7 0 8 0
donc, on a toujours ce qu'il faut, mais cette fois juste ce qu'il faut.
C'est quoi que j'ai compris de travers ?
Avec l'exemple suivant j'ai aussi un petit souci de compréhension.
Dans le même module j'ajoute : ================= Début ===================== Sub maProc2() Dim lg As Long Dim monTab(1 To 20) As Byte 'Dim i As Integer
maChaine = "AIDE" lg = StrPtr(maChaine) CopyMemory monTab(1), lg, LenB(maChaine)
For i = 1 To 20 Debug.Print i, monTab(i), Chr$(monTab(i)) Next
End Sub ================= Fin ======================= Et à l'appel j'obtiens : Form1.maProc2 1 84 T 2 53 5 3 28 4 0 5 252 ü 6 6 7 0 8 0
et le reste à 0. Je me gratte la tête, et je ne lis pas "AIDE".
Si en revanche je corrige ainsi : CopyMemory monTab(1), ByVal lg, LenB(maChaine)
j'obtiens Form1.maProc2 1 65 A 2 0 3 73 I 4 0 5 68 D 6 0 7 69 E 8 0 9 0 10 0 et le reste à 0.
J'avoue que je trouve plus lisible cette dernière version. D'ailleurs, si j'ai bien suivi (parfois ça arrive) c'est bien la correction qui m'a été proposée en réponse à mon premier message, pour éviter que VB plante.
Je préfère vérifier que je n'ai pas tout compris de travers, en corrigeant une erreur par une autre ...
Intéressant. Je crois que j'ai loupé les shémas en lisant ça dans Word
95, en rentrant à la maison je chercherai la visionneuse.
J'ai repris les exemples des pages 8 et 9, et je n'ai pas eu exactement
les mêmes résultats, peut-être quelque chose m'a-t-il échappé.
================= Début ===================== Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" _
(pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Dim maChaine As String
Public Sub maProc()
Dim monTab(19) As Byte
Dim i As Integer
For i = 0 To 19
Debug.Print i, monTab(i), Chr$(monTab(i))
Next
End Sub
================= Fin =======================
Résultat :
Form1.maProc
Len(maChaine) = 4
0 65 A
1 73 I
2 68 D
3 69 E
4 0
5 0
6 106 j
7 0
8 0
et le reste à 0.
J'ai un caractère aléatoire en position 6, si je fais plusieurs appels
successifs ce caractère ne sera pas forcément le même. Les quatre
premiers caractères, en revanche, sont bien ceux qu'on a voulu passer.
Si maintenant, en longueur, au lieu de LenB(maChaine), je mets
len(maChaine), je passe juste les caractères, et j'obtiens
0 65 A
1 73 I
2 68 D
3 69 E
4 0
5 0
6 0
7 0
8 0
donc, on a toujours ce qu'il faut, mais cette fois juste ce qu'il faut.
C'est quoi que j'ai compris de travers ?
Avec l'exemple suivant j'ai aussi un petit souci de compréhension.
Dans le même module j'ajoute :
================= Début ===================== Sub maProc2()
Dim lg As Long
Dim monTab(1 To 20) As Byte
'Dim i As Integer
maChaine = "AIDE"
lg = StrPtr(maChaine)
CopyMemory monTab(1), lg, LenB(maChaine)
For i = 1 To 20
Debug.Print i, monTab(i), Chr$(monTab(i))
Next
End Sub
================= Fin =======================
Et à l'appel j'obtiens :
Form1.maProc2
1 84 T
2 53 5
3 28
4 0
5 252 ü
6 6
7 0
8 0
et le reste à 0.
Je me gratte la tête, et je ne lis pas "AIDE".
Si en revanche je corrige ainsi :
CopyMemory monTab(1), ByVal lg, LenB(maChaine)
j'obtiens
Form1.maProc2
1 65 A
2 0
3 73 I
4 0
5 68 D
6 0
7 69 E
8 0
9 0
10 0
et le reste à 0.
J'avoue que je trouve plus lisible cette dernière version.
D'ailleurs, si j'ai bien suivi (parfois ça arrive) c'est bien la
correction qui m'a été proposée en réponse à mon premier message, pour
éviter que VB plante.
Je préfère vérifier que je n'ai pas tout compris de travers, en
corrigeant une erreur par une autre ...
Intéressant. Je crois que j'ai loupé les shémas en lisant ça dans Word 95, en rentrant à la maison je chercherai la visionneuse.
J'ai repris les exemples des pages 8 et 9, et je n'ai pas eu exactement les mêmes résultats, peut-être quelque chose m'a-t-il échappé.
================= Début ===================== Private Declare Sub CopyMemory Lib "kernel32" _ Alias "RtlMoveMemory" _ (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Dim maChaine As String
Public Sub maProc() Dim monTab(19) As Byte Dim i As Integer
For i = 0 To 19 Debug.Print i, monTab(i), Chr$(monTab(i)) Next
End Sub ================= Fin ======================= Résultat : Form1.maProc Len(maChaine) = 4 0 65 A 1 73 I 2 68 D 3 69 E 4 0 5 0 6 106 j 7 0 8 0 et le reste à 0.
J'ai un caractère aléatoire en position 6, si je fais plusieurs appels successifs ce caractère ne sera pas forcément le même. Les quatre premiers caractères, en revanche, sont bien ceux qu'on a voulu passer.
Si maintenant, en longueur, au lieu de LenB(maChaine), je mets len(maChaine), je passe juste les caractères, et j'obtiens
0 65 A 1 73 I 2 68 D 3 69 E 4 0 5 0 6 0 7 0 8 0
donc, on a toujours ce qu'il faut, mais cette fois juste ce qu'il faut.
C'est quoi que j'ai compris de travers ?
Avec l'exemple suivant j'ai aussi un petit souci de compréhension.
Dans le même module j'ajoute : ================= Début ===================== Sub maProc2() Dim lg As Long Dim monTab(1 To 20) As Byte 'Dim i As Integer
maChaine = "AIDE" lg = StrPtr(maChaine) CopyMemory monTab(1), lg, LenB(maChaine)
For i = 1 To 20 Debug.Print i, monTab(i), Chr$(monTab(i)) Next
End Sub ================= Fin ======================= Et à l'appel j'obtiens : Form1.maProc2 1 84 T 2 53 5 3 28 4 0 5 252 ü 6 6 7 0 8 0
et le reste à 0. Je me gratte la tête, et je ne lis pas "AIDE".
Si en revanche je corrige ainsi : CopyMemory monTab(1), ByVal lg, LenB(maChaine)
j'obtiens Form1.maProc2 1 65 A 2 0 3 73 I 4 0 5 68 D 6 0 7 69 E 8 0 9 0 10 0 et le reste à 0.
J'avoue que je trouve plus lisible cette dernière version. D'ailleurs, si j'ai bien suivi (parfois ça arrive) c'est bien la correction qui m'a été proposée en réponse à mon premier message, pour éviter que VB plante.
Je préfère vérifier que je n'ai pas tout compris de travers, en corrigeant une erreur par une autre ...
Gloops
Si j'ai bien lu le document proposé par François, les chaînes de caractères (ah pardon, les BSTR) sont systématiquement passées en valeur (du pointeur). Donc, si il y a "As String", devant on mettra "ByVal". Enfin si ça commence à se mettre un peu en place dans ma petite tête ...
Si j'ai bien lu le document proposé par François, les chaînes de
caractères (ah pardon, les BSTR) sont systématiquement passées en valeur
(du pointeur).
Donc, si il y a "As String", devant on mettra "ByVal". Enfin si ça
commence à se mettre un peu en place dans ma petite tête ...
Si j'ai bien lu le document proposé par François, les chaînes de caractères (ah pardon, les BSTR) sont systématiquement passées en valeur (du pointeur). Donc, si il y a "As String", devant on mettra "ByVal". Enfin si ça commence à se mettre un peu en place dans ma petite tête ...
Picalausa François
Hello,
<réponse inline>
"Gloops" a écrit dans le message de news: 42ba7ee8$0$25021$
J'ai un caractère aléatoire en position 6, si je fais plusieurs appels successifs ce caractère ne sera pas forcément le même. Les quatre premiers caractères, en revanche, sont bien ceux qu'on a voulu passer.
LenB("AIDE") renvoie 8 donc, on va copier 8 octets d'une chaine ANSI (1 octet/caractère) d'une chaine qui n'en comporte que 4... il y aura donc des données non réservées à la chaine après le 5ème (caractère nul de fin de chaine). De ce fait, elles peuvent contenir les données de n'importe quelle autre variable. La lecture n'est peut-être (quoi que?) pas bien méchant, mais maintenant, supposons qu'au lieu de lire ces caractères non initialisé, on écrive des caractères dans un espace qui ne nous est pas réservé... Et paf! c'est le buffer overrun. Cela explique que ça fonctionne avec Len.
Avec l'exemple suivant j'ai aussi un petit souci de compréhension. J'avoue que je trouve plus lisible cette dernière version. D'ailleurs, si j'ai bien suivi (parfois ça arrive) c'est bien la correction qui m'a été proposée en réponse à mon premier message, pour éviter que VB plante.
Positivement positif... l'exemple est erroné et passe un pointeur vers un pointeur au lieu de passer un pointeur vers le début de la chaine.
-- Picalausa François
Hello,
<réponse inline>
"Gloops" <gloops@niark.fr> a écrit dans le message de news:
42ba7ee8$0$25021$8fcfb975@news.wanadoo.fr...
J'ai un caractère aléatoire en position 6, si je fais plusieurs appels
successifs ce caractère ne sera pas forcément le même. Les quatre premiers
caractères, en revanche, sont bien ceux qu'on a voulu passer.
LenB("AIDE") renvoie 8
donc, on va copier 8 octets d'une chaine ANSI (1 octet/caractère) d'une
chaine qui n'en comporte que 4... il y aura donc des données non réservées à
la chaine après le 5ème (caractère nul de fin de chaine). De ce fait, elles
peuvent contenir les données de n'importe quelle autre variable.
La lecture n'est peut-être (quoi que?) pas bien méchant, mais maintenant,
supposons qu'au lieu de lire ces caractères non initialisé, on écrive des
caractères dans un espace qui ne nous est pas réservé... Et paf! c'est le
buffer overrun.
Cela explique que ça fonctionne avec Len.
Avec l'exemple suivant j'ai aussi un petit souci de compréhension.
J'avoue que je trouve plus lisible cette dernière version.
D'ailleurs, si j'ai bien suivi (parfois ça arrive) c'est bien la
correction qui m'a été proposée en réponse à mon premier message, pour
éviter que VB plante.
Positivement positif... l'exemple est erroné et passe un pointeur vers un
pointeur au lieu de passer un pointeur vers le début de la chaine.
J'ai un caractère aléatoire en position 6, si je fais plusieurs appels successifs ce caractère ne sera pas forcément le même. Les quatre premiers caractères, en revanche, sont bien ceux qu'on a voulu passer.
LenB("AIDE") renvoie 8 donc, on va copier 8 octets d'une chaine ANSI (1 octet/caractère) d'une chaine qui n'en comporte que 4... il y aura donc des données non réservées à la chaine après le 5ème (caractère nul de fin de chaine). De ce fait, elles peuvent contenir les données de n'importe quelle autre variable. La lecture n'est peut-être (quoi que?) pas bien méchant, mais maintenant, supposons qu'au lieu de lire ces caractères non initialisé, on écrive des caractères dans un espace qui ne nous est pas réservé... Et paf! c'est le buffer overrun. Cela explique que ça fonctionne avec Len.
Avec l'exemple suivant j'ai aussi un petit souci de compréhension. J'avoue que je trouve plus lisible cette dernière version. D'ailleurs, si j'ai bien suivi (parfois ça arrive) c'est bien la correction qui m'a été proposée en réponse à mon premier message, pour éviter que VB plante.
Positivement positif... l'exemple est erroné et passe un pointeur vers un pointeur au lieu de passer un pointeur vers le début de la chaine.
-- Picalausa François
Zoury
> Donc, si il y a "As String", devant on mettra "ByVal".
Exact !
Enfin si ça commence à se mettre un peu en place dans ma petite tête ...
Ça m'a l'air d'être le cas. :O)
-- Cordialement Yanick MVP pour Visual Basic
> Donc, si il y a "As String", devant on mettra "ByVal".
Exact !
Enfin si ça
commence à se mettre un peu en place dans ma petite tête ...