Pointeur en VB6 [Résolu]

matteli 38 Messages postés jeudi 23 novembre 2000Date d'inscription 14 mars 2007 Dernière intervention - 31 janv. 2007 à 17:00 - Dernière réponse : PCPT 13368 Messages postés lundi 13 décembre 2004Date d'inscription 3 février 2018 Dernière intervention
- 6 févr. 2007 à 20:58
Un truc tout bête.

J'aimerais avoir un pointeur vers une variable.
Je n'ai pas réussi à faire ça autrement qu'avec une classe.

Y a t'il un moyen de faire ça simplement.

Merci
Afficher la suite 

Votre réponse

18 réponses

cs_rt15 3982 Messages postés mardi 8 mars 2005Date d'inscription 7 novembre 2014 Dernière intervention - 2 févr. 2007 à 11:42
+3
Utile
Salut,


Comme dit pcpt, faut voire l'usage.

Mais on peut toujours s'en sortir avec les fonctions qu'il cite je pense.


Par exemple ce C :

===========================================

#include <stdio.h>


int main(int argc, char *argv[])

{

  long a = 1;

  long b = 2;

  long * aPtr, * bPtr, * tempPtr;


  aPtr = &a;

  bPtr = &b;

 

  printf("La valeur pointée par aPtr est %d\n", *aPtr);

  printf("La valeur pointée par bPtr est %d\n", *bPtr);

 

  /* On échange les adresses pointées par aPtr et bPtr */

  tempPtr = aPtr;

  aPtr = bPtr;

  bPtr = tempPtr;

 

  printf("La valeur pointée par aPtr est %d\n", *aPtr);

  printf("La valeur pointée par bPtr est %d\n", *bPtr); 

 

  return 0;

}

===========================================


Ce traduit par exemple très simplement par :

===========================================


Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)


Private Sub Command1_Click()

Dim aPtr As Long

Dim bPtr As Long

Dim a As Long

Dim b As Long

Dim tempPtr As Long


a = 1

b = 2

aPtr = VarPtr(a)

bPtr = VarPtr(b)


Debug.Print vbCrLf & "==================================="

Debug.Print "La valeur pointée par aPtr est " & CStr(ValLong(aPtr))

Debug.Print "La valeur pointée par bPtr est " & CStr(ValLong(bPtr))


' On échange les adresses pointées par aPtr et bPtr

tempPtr = aPtr

aPtr = bPtr

bPtr = tempPtr


Debug.Print "La valeur pointée par aPtr est " & CStr(ValLong(aPtr))

Debug.Print "La valeur pointée par bPtr est " & CStr(ValLong(bPtr))


End Sub


' Récupère un entier pointé

Private Function ValLong(ByVal adress As Long) As Long

CopyMemory ValLong, ByVal adress, 4

End Function

===========================================
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_rt15
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 31 janv. 2007 à 17:12
0
Utile
Le principe des pointeurs n'existe pas en VB6.

Tu peut toujours récuperer l'adresse d'une variable avec VarPtr, mais ça te donnera juste l'adresse en mémoire pas plus.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Commenter la réponse de cs_casy
matteli 38 Messages postés jeudi 23 novembre 2000Date d'inscription 14 mars 2007 Dernière intervention - 31 janv. 2007 à 17:20
0
Utile
Ok merci c'est bien ce que je pensais.

C'est bien dommage.

Je ne comprends pas pourquoi ils ont réservé la commande 'set' seulement à des objets et pas aussi à des variables.
Commenter la réponse de matteli
PCPT 13368 Messages postés lundi 13 décembre 2004Date d'inscription 3 février 2018 Dernière intervention - 1 févr. 2007 à 02:40
0
Utile
salut,
faut voir ton usage... il y a peut-être quelquechose avec non seulement avec varptr, mais aussi avec objptr et strptr, ainsi que l'api copymemory

++
PCPT  [AFCK]
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
Commenter la réponse de PCPT
matteli 38 Messages postés jeudi 23 novembre 2000Date d'inscription 14 mars 2007 Dernière intervention - 2 févr. 2007 à 19:10
0
Utile
En effet, ça pourrait fonctionner.

Dans mon programme qui est un jeu, je veux laisser la possibilité aux moddeurs (de ce jeu) de créer leur propre fenêtre d'information en affichant les données qu'ils veulent.
Pour celà, il suffira de créer un fichier texte avec les infos de la fenêtre (taille, image de fond , texte à afficher).
Le texte à afficher peut être par exemple :
"Déclarer la guerre à %%countryselected"
Contryselected prendra la valeur du pays sélectionné.

Lors du chargement du jeu, ça donne en pseudo code :

phrase(1).texte="Déclarer la guerre à "
phrase(1).pointeur=Null
phrase(2).texte=Null
phrase(2).pointeur=pointage vers la variable qui contient le nom du pays sélectionné

Comme ça lors de l'affichage de la fenêtre, je passe en revue le tableau phrase et elle s'affiche rapidement.

Voilà je sais pas si j'ai été clair et en tout cas, vous vous l'avez été et je pense que je vais pouvoir continuer.

Pour ceux que ça intéresse le projet se discute sur :
histemul.myfreeforum.org

Merci
Commenter la réponse de matteli
matteli 38 Messages postés jeudi 23 novembre 2000Date d'inscription 14 mars 2007 Dernière intervention - 3 févr. 2007 à 15:21
0
Utile
J'y pense. Ca risque d'être compliqué en fait, vu que ma variable est une chaine de caractère dont je ne connais à priori pas la longueur.
Commenter la réponse de matteli
cs_rt15 3982 Messages postés mardi 8 mars 2005Date d'inscription 7 novembre 2014 Dernière intervention - 5 févr. 2007 à 10:04
0
Utile
A ce que j'ai compris, tu n'as pas vraiment besoin de pointeurs.


1 Tu récupère "Déclarer la guerre à %%countryselected" dans un fichier texte et tu le met dans une variable text.

2 Tu as le nom du pay dans la variable nompays.

3 Tu fais un text = replace(text, "%%countryselected", nompays)


Et tu fais de même avec tous tes mots clés en %%. Comme des macros quoi.


En VB6, il n'est que très rarement intéressant d'utiliser les
pointeurs. On s'en sert avant tout pour la compatibilité avec le Win32
( et peut être parfois pour faire de l'opimisation.)
Commenter la réponse de cs_rt15
matteli 38 Messages postés jeudi 23 novembre 2000Date d'inscription 14 mars 2007 Dernière intervention - 5 févr. 2007 à 20:24
0
Utile
C'est vrai mais est ce que cette fontion n'est pas un peu lente? car elle devra s'insérer dans une boucle déjà bien pleine et qui doit s'exécuter tous les 30/100 de seconde (sauf si j'insère un marqueur pour indiquer quand il y  a un changement de pays sélectionné).
Commenter la réponse de matteli
PCPT 13368 Messages postés lundi 13 décembre 2004Date d'inscription 3 février 2018 Dernière intervention - 5 févr. 2007 à 22:30
0
Utile
replace pour le principe, mais il faudra sûrement passer par instr et boucler.
je suis de même avis que rt15, non seulement l'utilisation du pointeur est ici inutile, mais tu risques surtout de faire planter une paire d'appli (la tienne, explorer, autre) en cas d'opération trop longue à executer (puisque tu boucles).

2e point, tu executes cette procédure 30 fois par seconde? il y a sans doute un souci de conception là....

++
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
Commenter la réponse de PCPT
matteli 38 Messages postés jeudi 23 novembre 2000Date d'inscription 14 mars 2007 Dernière intervention - 6 févr. 2007 à 14:51
0
Utile
Je l'execute tous les 30/100 car c'est le taux de raffraichissement de mon image et que la contenu de cette phrase peut changer  tout moment.

Que pensez-vous d'utiliser une petite classe toute simple.

Une classe : TextVaria
avec dedans :
Private mvarTexte As String 'copie locale
Public Property Let Texte(ByVal vData As String)
    mvarTexte = vData
End Property
Public Property Get Texte() As String
    Texte = mvarTexte
End Property

Je délcare ma variable PaysSélectionné en textvaria, sa propriété texte change à chaque fois que le pays sélectionné change.
De l'autre côté, j'ai un tableau de textvaria dans lequelle je mets soit du texte fixe :
"Déclarez la guerre à ",
soit une affectation vers PaysSélectionné avec Set.

En tout cas, je retiens la solution "replace" qui est plus simple.
Commenter la réponse de matteli
PCPT 13368 Messages postés lundi 13 décembre 2004Date d'inscription 3 février 2018 Dernière intervention - 6 févr. 2007 à 14:57
0
Utile
beh avec une classe tu pourrais gérer un évènement qui lui forcerait le refresh, çà t'éviterait de retester le texte à chaque intervalle.
Commenter la réponse de PCPT
cs_rt15 3982 Messages postés mardi 8 mars 2005Date d'inscription 7 novembre 2014 Dernière intervention - 6 févr. 2007 à 17:44
0
Utile
Ton système de classe accélererait certainement la reconstruction de la
chaîne. Mais c'est évident qu'il faut essayer de la reconstituer que
quand c'est nécessaire...


En effet, l'opérateur & de concaténation à l'air tout petit tout
mignon comme ça, mais il consomme un paquet de CPU. La comparaison de
deux chaînes serat par exemple beaucoup plus rapide que leur
concaténation.


Pour ce qui est du replace, le instr de pcpt s'avèrerait certainement
plus rapide dans ton cas : Il ferait tous les remplacements en un
parcourt, moyennant à peine plus de code à développer.
Commenter la réponse de cs_rt15
PCPT 13368 Messages postés lundi 13 décembre 2004Date d'inscription 3 février 2018 Dernière intervention - 6 févr. 2007 à 19:25
0
Utile
j'ai fais la proc avec len (au lieu de instr), çà donne çà :

Option Explicit

Private Sub Form_Load()
    Const TOTREAT As String =  "Dans le pays %%countryselected,
%%pseudo a déclaré la guerre ce %%date à %%time avec son arme favorite :
%%extraweapon"
    Dim aArgs(4) As String
    Dim aStr(4) As String
    
    aArgs(0) = "%%countryselected"
    aArgs(1) = "%%pseudo"
    aArgs(2) = "%%date"
    aArgs(3) = "%%time"
    aArgs(4) = "%%extraweapon"

    aStr(0) = "France"
    aStr(1) = "matteli"
    aStr(2) = Format$(Date, "DDDD DD MMM YYYY")
    aStr(3) = CStr(Time)
    aStr(4) = "l'aubergine accompagnée de sa
farce à la rubarbe et au hachi"

    MsgBox TOTREAT & vbCrLf & vbCrLf & MyReplace(TOTREAT, aArgs,
aStr)
    
    Erase aArgs
    Erase aStr
    
    Unload Me
End Sub
'
'
Function MyReplace(ByVal Expression As String, Find() As String, Replace() As
String) As
String
'   Replace() doit avoir soit une seule
occurence, soit autant que Find()
    Dim i As Long, j As Long, LboundReplace As Integer, LenFind As Integer
    LboundReplace = LBound(Replace)
    
    For i = 1 To Len(Expression)
        For j = LBound(Find) To UBound(Find)
            LenFind = Len(Find(j))
            If LboundReplace = UBound(Replace) Then                If Mid$(Expression, i, LenFind) Find(j) Then Expression
Left$(Expression, i -
1) & Replace(LboundReplace) &
Right$(Expression,
Len(Expression) - i -
LenFind + 1)
            Else                If Mid$(Expression, i, LenFind) Find(j) Then Expression
Left$(Expression, i -
1) & Replace(j) & Right$(Expression, Len(Expression) - i - LenFind +
1)
            End If
        Next j
''       on peut ajouter cette
ligne pour les très très grandes chaînes à traiter (disons pour plus de 20'000
caractères)
'        If i And 4096 Then
DoEvents
    Next i
    MyReplace = Expression
End Function

<small>Coloration
syntaxique automatique [AFCK] </small>
       

je vais essayer avec instr puis le simple remplace pour voir les temps d'execution...
je vous tiens au courant

++
PCPT  [AFCK]
<hr size ="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
Commenter la réponse de PCPT
PCPT 13368 Messages postés lundi 13 décembre 2004Date d'inscription 3 février 2018 Dernière intervention - 6 févr. 2007 à 20:02
0
Utile
bon, voici de 3 manières : len, instr, et replace

le code ici :

Option Explicit

Private Sub Form_Load()
    Const TOTREAT As String =  "Dans le pays %%countryselected,
%%pseudo a déclaré la guerre ce %%date à %%time avec son arme favorite :
%%extraweapon"
    Dim aArgs(4) As String
    Dim aStr(4) As String
    
    aArgs(0) = "%%countryselected"
    aArgs(1) = "%%pseudo"
    aArgs(2) = "%%date"
    aArgs(3) = "%%time"
    aArgs(4) = "%%extraweapon"

    aStr(0) = "France"
    aStr(1) = "matteli"
    aStr(2) = Format$(Date, "DDDD DD MMM YYYY")
    aStr(3) = CStr(Time)
    aStr(4) = "l'aubergine accompagnée de sa
farce à la rubarbe et au hachi"

'   TEST
AVEC UNE CLASSE CHRONO EXTéRIEURE, CODE NON FOURNI
    Dim i As Long, sRes As String, cT As New AfCls_Timer
    Dim cSum As Currency, cMin As Currency, cMax As Currency, cV As Currency
    cSum = 0
    cMin = 10000
    cMax = 0
    
    For i = 1 To 2000
        cT.StartChrono
        sRes = MyReplace_LEN(TOTREAT, aArgs, aStr)
        cT.StopChrono
        cV = cT.QueryPerformanceValue
        cSum = cSum + cV
        If cMin > cV Then cMin = cV
        If cMax < cV Then cMax = cV
    Next i    Debug.Print "LEN        min " & cMin & "   max
" & cMax & " moy
= " & cSum / 2000
    DoEvents
    

    cSum = 0
    cMin = 10000
    cMax = 0
    
    For i = 1 To 2000
        cT.StartChrono
        sRes = MyReplace_LEN(TOTREAT, aArgs, aStr)
        cT.StopChrono
        cV = cT.QueryPerformanceValue
        cSum = cSum + cV
        If cMin > cV Then cMin = cV
        If cMax < cV Then cMax = cV
    Next i    Debug.Print "INSTR      min " & cMin & "   max
" & cMax & " moy
= " & cSum / 2000
    DoEvents

    cSum = 0
    cMin = 10000
    cMax = 0
    
    For i = 1 To 2000
        cT.StartChrono
        sRes = MyReplace_LEN(TOTREAT, aArgs, aStr)
        cT.StopChrono
        cV = cT.QueryPerformanceValue
        cSum = cSum + cV
        If cMin > cV Then cMin = cV
        If cMax < cV Then cMax = cV
    Next i    Debug.Print "REPLACE    min " & cMin & "   max
" & cMax & " moy
= " & cSum / 2000
    
    Erase aArgs
    Erase aStr
    
    Unload Me
End Sub
'
'
Function MyReplace_LEN(ByVal Expression As String, Find() As String, Replace() As
String) As
String
'   Replace() doit avoir soit une seule
occurence, soit autant que Find()
    Dim i As Long, j As Long, LboundReplace As Integer, LenFind As Integer
    LboundReplace = LBound(Replace)
    
    For i = 1 To Len(Expression)
        For j = LBound(Find) To UBound(Find)
            LenFind = Len(Find(j))
            If LboundReplace = UBound(Replace) Then                If Mid$(Expression, i, LenFind) Find(j) Then Expression
Left$(Expression, i -
1) & Replace(LboundReplace) &
Right$(Expression,
Len(Expression) - i -
LenFind + 1)
            Else                If Mid$(Expression, i, LenFind) Find(j) Then Expression
Left$(Expression, i -
1) & Replace(j) & Right$(Expression, Len(Expression) - i - LenFind +
1)
            End If
        Next j
''       on peut ajouter cette
ligne pour les très très grandes chaînes à traiter (disons pour plus de 20'000
caractères)
'        If i And 4096 Then
DoEvents
    Next i
    MyReplace_LEN = Expression
End Function
'
'
Function MyReplace_INSTR(ByVal Expression As String, Find() As String, Replace()
As String) As String
'   Replace() doit avoir
soit une seule occurence, soit autant que Find()
    Dim i As Long, lPos As Long, LboundReplace As Integer
    LboundReplace = LBound(Replace)
    
    For i = LBound(Find) To UBound(Find)
        lPos = InStr(1, Expression, Find(i))
        If lPos > 0 Then
            If LboundReplace = UBound(Replace) Then
                Expression = Left$(Expression, lPos - 1) & Replace(LboundReplace) & Right$(Expression, Len(Expression) - lPos - Len(Find(i)) + 1)
            Else
                Expression = Left$(Expression, lPos - 1) & Replace(i) & Right$(Expression, Len(Expression) - lPos - Len(Find(i)) + 1)
            End If
        End If
    Next i
    MyReplace_INSTR = Expression
End Function
'
'
Function MyReplace_REPLACE(ByVal Expression As String, Find() As String, Replace()
As String) As String
'   Replace() doit avoir
soit une seule occurence, soit autant que Find()
    Dim i As Long, j As Long, LboundReplace As Integer
    LboundReplace = LBound(Replace)
    
    For i = LBound(Find) To UBound(Find)
        If LboundReplace = UBound(Replace) Then
            Expression = VBA.Replace(Expression, Find(i), Replace(LboundReplace))
        Else
            Expression = VBA.Replace(Expression, Find(i), Replace(i))
        End If
    Next i
    MyReplace_REPLACE = Expression
End Function

<small>Coloration
syntaxique automatique [AFCK] </small>
       

la trace ici :
LEN        min 0,523   max 16,1803 moy = 0,5677654INSTR      min 0,53   max 48,3123 moy = 0,5988921REPLACE    min 0,523   max 31,0567 moy = 0,5797652

je suis assez étonné, c'est très comparable....
il faudrait surement essayer sur plus de caractères et enlever la possibilité de remplacer tous les arguments par la même chaîne

juste ce dernier facteur, voici la trace :
LEN        min 0,3188   max 18,142 moy = 0,36281165INSTR      min 0,319   max 18,8937 moy = 0,35847635REPLACE    min 0,319   max 8,9271 moy = 0,35953475

umm, pas de conclusion

++
PCPT  [AFCK]
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
Commenter la réponse de PCPT
PCPT 13368 Messages postés lundi 13 décembre 2004Date d'inscription 3 février 2018 Dernière intervention - 6 févr. 2007 à 20:13
0
Utile
mais quel boulet des fois !!!!!

j'ai mesuré 3 fois la même proc, normal que çà soit similaire ^^

bon, la trace normale :LEN        min 0,5199   max 18,0118 moy = 0,56826895INSTR      min 0,0154   max 0,6456 moy = 0,0160732REPLACE    min 0,0249   max 5,0791 moy = 0,0292755

et en enlevant le test du replace(0) à une seule occurence :LEN        min 0,319   max 19,3932 moy = 0,36290615INSTR      min 0,0148   max 0,1995 moy = 0,0151777REPLACE    min 0,024   max 3,3957 moy = 0,02798635

conclusion : il faut bien utiliser INSTR qui est le plus rapide

++
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
Commenter la réponse de PCPT
PCPT 13368 Messages postés lundi 13 décembre 2004Date d'inscription 3 février 2018 Dernière intervention - 6 févr. 2007 à 20:44
0
Utile
grrrrrrrr!!!
c'est un replace unique là, je n'ai pas bouclé :(

bref, c'est corrigé et c'est toujours plus le rapide.
code disponible ici :
http://www.codyx.org/snippet_replace-masse-remplacer-chaines-autres-seule-operation_296.aspx

++ ;)
PCPT  [AFCK]
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
Commenter la réponse de PCPT
matteli 38 Messages postés jeudi 23 novembre 2000Date d'inscription 14 mars 2007 Dernière intervention - 6 févr. 2007 à 20:49
0
Utile
Bon je retiens Instr alors et je lâche ma classe.

Merci pour tous ces tests PCPT.
Commenter la réponse de matteli
PCPT 13368 Messages postés lundi 13 décembre 2004Date d'inscription 3 février 2018 Dernière intervention - 6 févr. 2007 à 20:58
0
Utile
que la fonction soit rapide, ok, mais ne lâche pas la classe pour autant, tu ne devrais pas re-générer ta chaîne à chaque intervalle de timer mais bien à chaque changement réelle => évènement de ta classe
Commenter la réponse de PCPT

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.