PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 2018
-
10 juil. 2006 à 15:42
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 2018
-
3 déc. 2006 à 19:04
[VB6]
Bonjour,
le problème est ici simplifié pour être plus facilement cerné.
sur une Form, une TextBox.
j'attache cette TB à une collection qui elle-même l'attache à une classe WithEvents pour des traitements à l'interne.
(donc la classe contenant la collection ne sert qu'à accéder rapidement à la déclaration de la sous-classe autonome)
le code ci-dessous pour éclairer :
la Form contient 2 TextBox (pour test)
Text1(1) (<-- Text1 indéxé, évidemment)
Text2
'= -=-=-=-=-=-=-=-=
' FORM : Form1.frm
'=-=-=-=-=-=-=-=-=
'
'
Option Explicit
Private mTBs As New TextBoxes
'
'
Private Sub Form_Load()
mTBs.Add Text1(1)
'mTBs.Add Text2
End Sub
'
Private Sub Form_Unload(Cancel As Integer)
'mTBs.Remove Text1(1)
Set mTBs = Nothing
End Sub
'=-=-=-=-=-=-=-=-=-=-=-
' CLASS : TextBoxes.cls
'=-=-=-=-=-=-=-=-=-=-=-
'
'
Option Explicit
'
Private mCol As Collection
'
Public Property Get Count() As Long
Count = mCol.Count
End Property
'
Public Property Get NewEnum() As IUnknown
Set NewEnum = mCol.[_NewEnum]
End Property
'
Public Property Get Item(vntIndexKey As Variant) As Cls_TxtBox
Set Item = mCol(vntIndexKey)
End Property
'
'
Private Sub Class_Initialize()
Set mCol = New Collection
End Sub
'
Private Sub Class_Terminate()
Set mCol = Nothing
End Sub
'
'
Public Sub Add(ByRef oTxtBox As Variant)
Dim AfTxtBox As New Cls_TxtBox
AfTxtBox.SetObject oTxtBox
mCol.Add AfTxtBox
Set AfTxtBox = Nothing
End Sub
'
Public Sub Remove(ByRef oTxtBox As Variant)
' Dim i As Long
' If mCol.Count > 0 Then
' For i = 1 To mCol.Count
' If mCol.Item(i).Object Is oTxtBox Then mCol.Remove i: Exit For
' Next i
' End If
End Sub
'=-=-=-=-=-=-=-=-=-=-=-=
' CLASS : Cls_TxtBox.cls
'=-=-=-=-=-=-=-=-=-=-=-=
'
'
Option Explicit
'
Private WithEvents mTxt As TextBox
'
'
Public Property Get Object() As TextBox
Set Object = mTxt
End Property
'
'
Private Sub Class_Initialize()
Set mTxt = Nothing
End Sub
'
Private Sub Class_Terminate()
Set mTxt = Nothing
End Sub
'
'
Public Function SetObject(new_mTxt As Variant) As Boolean
Dim oTB As TextBox, Index As Integer
On Local Error Resume Next
Index = new_mTxt.Index
If Err.Number = 343 Then
' pas un tableau donc contrôle non-indéxé
Err.Clear
Set oTB = new_mTxt
Set mTxt = oTB
SetObject = True
ElseIf Err.Number = 0 Then
On Error GoTo 0
' pas d'erreur, il est indéxé
MsgBox new_mTxt.Name & "(" & new_mTxt.Index & ")"
Set oTB = new_mTxt
MsgBox oTB.Index
Set mTxt = oTB
SetObject = True
Else
' autre erreur mais il n'y a pas de raison (tant qu'on met bien un txtbox)
Err.Clear
Set mTxt = Nothing
SetObject = False
End If
Set oTB = Nothing
End Function
'
'
Private Sub mTxt_KeyPress(KeyAscii As Integer)
Debug.Print mTxt.Name & "_KeyPress : " & Chr$(KeyAscii)
End Sub
le code est intégral, çà va très vite à tester...
il suffit juste d'inverser la quote
mTBs.Add Text1(1)
'mTBs.Add Text2
(et de regarder la fenêtre de debug au Txt_Change pour Text2 fonctionnel)
pour mon projet réel je peux contourner le problème en n'utilisant pas de groupe de contrôles mais la question subsiste...
merci déjà d'avoir lu jusqu'ici
++
PCPT [AFCK]
<hr size ="2" width="100%" />Prenez un instant pour répondre à ce sondage svp
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 3 déc. 2006 à 05:16
T'eh, on va relancer un vieux topic
Et si c'était tout simplement impossible de cette façon ?
Il est probable qu'il ne soit pas possible de pointer ton objet mTxt sur un controle lui est indexé.
Au cas où, regarde ce lien.
@++
<hr size="2" width="100%" />
--Mortalino--
Le mystérieux chevalier, "Provençal, le Gaulois"
<!--
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 11 juil. 2006 à 07:14
Salut PCPT,
et en l'indexant pas par sa propriété Index, mais avec le Tag ?
Y a pas moyen de le gérer ainsi ?
Tu crées un évènement Txt_Change (ou KeyPress) qui gère tes contrôles avec cette propriété Tag (bien entendu, elle est la même pour tous tes CheckBox)
Méthode barbare, certe, mais ça m'a enlevé une épine du pied plusieurs fois !
J'ai pas VB6 sur moi donc je n'ai pu tester ton code...
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 11 juil. 2006 à 09:56
salut Mortalino,
pas essayé avec le Tag ou autre puisque je vois comment contourner le problème dans le projet actuel mais pas pour autant "pourquoi"
et ici de toutes façons çà serait pareil. admettons un Tag à "yep", si Tag "yep" (au .Add.) alors .SetObject ...> même résultat
<hr size="2" width="100%" />Prenez un instant pour répondre à ce sondage svp
Vous n’avez pas trouvé la réponse que vous recherchez ?
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 11 juil. 2006 à 14:29
si, c'est logique. mTxt est un objet unique donc ne renvoyant pas ses évènements avec "Index as integer" en paramètre. et il est impossible de déclarer un tableau d'objets (ou d'objets indexés) withevents.
mais le problème reste le même :
nouveau projet, 2 TB indéxées, 2 boutons :
Option Explicit
Dim o As TextBox
'
'
Private Sub Form_Load()
Text1(0).Text = "zone 1"
Text1(1).Text = "zone 2"
End Sub
'
'
Private Sub Command1_Click()
Set o = Text1(0)
MsgBox o.Text
Set o = Nothing
End Sub
'
Private Sub Command2_Click()
Set o = Text1(1)
MsgBox o.Text
Set o = Nothing
End Sub
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 11 juil. 2006 à 14:55
Viens faire du VBA c'est plus simple...
C'est vrai que t'as pas de chance, tu nous demandes des choses assez complexes !
En fait, si toi tu sais pas, bah nous non plus (sauf peut-être Rey !)
Désolé que l'aide ne marche que dans un sens. (ah ! pour l'instant!)
Mais comme je crains dégùn (personne), je copie ton code et regarde cet aprem.
(même si je sais que je vais galérer, on ne sait jamais, une lueur d'espoir, ou de la chance peut arriver)
Et puis, c'est comme le coup du registre, même si je ne t'ai été d'aucune aide, cela m'a permis d'apprendre des choses (c'est au moins ça, lol)
Bon courage à toi,
@++
--Mortalino--
Le Mystérieux Chevalier "Provençal, le Gaulois"
ou Quand on touche le fond de VB (au sens Cinquième dimension).
401740 PCPT, je n'ai pas de solution parfaite à ton problème, mais il existe des solutions. Tu en a trouvé une.
Tu avais donc remarqué que si tu ne prenais pas en charge les évènements avec le membre mTxt de ta classe Cls_TxtBox, les affectations fonctionnent, même avec les contrôles indexés. On pourrait donc imaginer un aiguillage de classe où tu gèrerais les contrôles non indexés dans Cls_TxtBox avec évènements, et les contrôles indexés dans Cls_TxtBoxGrp sans évènements. Au moins, tu aurais bien aussi les références aux objets indexés mais pas leurs évènements. Et à la classe d'emballage TextBoxes de gérer l'aiguillage de façon propre.
Il existe une autre solution qui ne fonctionne pas avec les contrôles intrinsèques de VB, mais avec les contrôles utilisateurs. Je ne connais pas ton besoin exact, et il se peut donc que cette solution ne convienne pas du tout. Cependant, elle a le mérite de savoir récupérer les références à des contrôles chargés dynamiquement, tout en recevant les évènements de ceux-ci. Elle utilise pour cela l'objet VB.VBControlExtender.
Ensuite, pour ajouter de la matière à réflexion, je remarque :
- que la propriété Index d'un contrôle utilisateur appartient à l'objet Extender de VB (dixit MSDN).
- que, dans ton exemple TypeName(Text1) renvoie Object, que TypeName(Text1(1)), TypeName(Text2), TypeName(Me.Controls("Text1")(1)), TypeName(Me.Controls.Item("Text1")(1)) renvoient TextBox, mais que VB donne une signature d'évènement différente pour Text1 et Text2. Etant donné qu'une même classe ne peut déclarer 2 évènements de même nom, mais de signature différente, on peut se dire qu'on a affaire à 2 classes distinctes et à un mappage de noms de classe, via la classe d'emballage Controls et le jeu des propriétés par défaut (propriété cachée .[_Default] As String), hypothèses bien sûr car je ne saurais pas le faire aussi proprement en VB (mais je pense bien qu'ils ne le font pas en VB).
Tout cela m'amène à croire que c'est l'objet Extender des ActiveX (utilisateurs) qui gère l'aiguillage des contrôles indexés (intrinsèques), via l'objet Controls de VB, et que les concepteurs ont choisi de volontairement cacher l'accès à cet objet, ce qui nous empêche de traiter directement le problème avec les contrôles intrinsèques.
Pour =647037 mortalino, on notera que les développeurs de VBA n'ont pas fait le même choix, puisqu'ils ont choisit de ne pas implémenter la possibilité de faire des groupes de contrôles dans le designer des UserForm, ni d'implémenter l'objet VB.VBExtender, ni d'implémenter les contrôles utilisateur (heureusement, il reste les modules de classe cf:http://www.vbfrance.com/codes/TABLEAU-CONTROLES-DYNAMIQUES-AVEC-EVENEMENTS_37219.aspx)
espérant faire avancer le débat,
à+
rvblog<sup>n
Je veux ton bien....et je l'aurais....mais jamais avant la page 4 des derniers échanges</sup>
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 15 sept. 2006 à 14:25
salut rvblog,
je ne m'attendais plus à une participation sur ce topic...
selon mon utilisation, je ne peux utiliser le me.controls car la collection est déclarée public pour plusieurs forms.
tu me diras, je peux lister les forms dans une collection puis blabla, mais c'est beaucoup pour peu (le but pour moi était de centraliser des restrictions différentes selon des paramètres pour tous les objets TextBox, indéxés ou non, d'un même projet, en 1 ligne de code (2 avec le déchargement en sortie)).
pour le côté dynamique, mes contrôles sont indexés mais chargés en mode conception. l'objet extender n'est donc pas interrogeable.
pourquoi les collections indexés sont cachées par VB, en voilà une question intéressante.
pourquoi ne peut-on pas faire de groupe de contrôles comme les optionsbuttons sans passer par des méthodes maison farfelues, là aussi c'est mystère...
peut-être peut-on faire quelquechose avec le handle, objptr et copymemory...
çà serait à creuser, plus le temps actuellement ^^
le topic reste ouvert
merci de ta participation
@+
<hr size="2" width="100%" />Prenez un instant pour répondre à ce sondage svp
rvblog
Messages postés792Date d'inscriptionvendredi 4 mars 2005StatutMembreDernière intervention12 juin 20127 18 sept. 2006 à 23:48
Au fait, on peut faire un groupe de contrôles comme les options buttons, sans passer par des méthodes maisons farfelues...:
Mets ça dans un UserControl vide :
Private m_Value As OLE_OPTEXCLUSIVE
Public Property Get Value() As OLE_OPTEXCLUSIVE
Value = m_Value
End Property
Public Property Let Value(ByVal vNewValue As OLE_OPTEXCLUSIVE)
m_Value = vNewValue
UserControl.PropertyChanged "Value"
If m_Value Then
UserControl.BackColor = vbRed
Else
UserControl.BackColor = vbBlue
End If
End Property
Private Sub UserControl_Click()
Me.Value = Not (Me.Value)
End Sub
Dans les attributs de procédure (avancé) de Value, mets ID de la procédure sur (Par Defaut), pour que le conteneur sache sur quelle propriété agir.
Ajoutes 2 instance groupées de ton UserControl sur un Form, affiche le Form, testes et sois ravi!
à+
rvblog<sup>n
Je veux ton bien....et je l'aurais....mieux vaut tard...que trop tard!</sup>
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 19 sept. 2006 à 00:02
alors çà c'est bon !!!!
me voilà ravi
je garde précieusement de côté.
çà ne m'aide pas pour ce topic mais j'espère m'en servir pour une idée qui me trotte depuis un moment (peut-être en 2007 )
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 3 déc. 2006 à 13:25
salu salut...
lien très très interessant !
résumé : MSDN ne dit pas vraiment pourquoi mais CE N'EST PAS POSSIBLE.
supposition de l'auteur : les objets pouvant être chargés dynamiquement, le conteneur ne saurait plus "de où" récupérer les évènements en cas de destruction d'une des instances de la collection de classe ou en càs de sa ré-organisation
merci de tes recherches mortalino, çà m'évite tout espoir...
il y a tout de même forcément un paliatif (sinon on ne pourrait pas indexer d'objets), je me remettrai à ce code un jour et informerai des suites
++
<hr size="2" width="100%" />Prenez un instant pour répondre à ce sondage svp
je suis navré, mais je suis obligé de m'inscrire en faux,
en effet, si on ne peut pas (sait?) affecter une "référence à un contrôle TextBox indexé" dans une variable de type TextBox, succeptible de recevoir des évènements (donc avec WithEvents), on peut (sait?) affecter une "référence à un contrôle utilisateur indexé" dans une variable du même type que le contrôle utilisateur, et succeptible de recevoir des évènements (toujours avec WithEvents).
Le débat (et l'espoir qui s'en suit) reste donc toujours ouvert!
Dans la même famille de limitations, on retrouve :
- Le type VBControlExtender qui ne permet pas d'affecter une variable de type "objet intrinsèque VB". Pourtant le type VBControlExtender est capable de récupérer tous les évènements de n'importe quel autre type d'objet.
- La collection Controls (celle à qui on s'adresse, intrinsèquement, lorsque l'on écrit Text1(0)) n'est pas une collection VB (dixit le MSDN, et facilement vérifiable, en essayant d'affecter la collection Controls à une variable de contrôle du type Collection).
- VB ne tolère pas que l'on essaye de récupérer les évènements d'un objet de type générique (donc, type Object, type Control, ...), et Me.Controls("Text1") est de type Object, alors que Me.Controls("Text1")(0) est de type TextBox et est parfaitement transtypable en type Control.
- et surtout, VB sait le faire lorsque le contrôle est situé sur un formulaire en instance conception. La variable est une variable implicite, passant par la collection Controls (ou par un raccourci).
Bref, il doit y avoir moyen de moyenner!
à+
PS : PCPT, impressionnant le RTB! je travaillais moi-même sur une revue d'un RTB, mais orienté génération d'un code HTML plus propre (factorisation des styles, comme Word ou les CSS). J'ai de bon résultats (environ 60% en taille moyenne sur des grosses pages), mais je bute encore sur l'interface de saisie et son raffraichissement intelligent, mais ça va venir (il semble que j'ai moins de temps dispo qu'il m'en faudrait!). Il faut que j'active, car c'est une des composants principaux de mon futur Forum Explorer (toi aussi peut-être?).
rvblog<sup>n
Je veux ton bien....et je l'aurais....mieux vaut tard...que trop tard!</sup>
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 3 déc. 2006 à 14:34
Salut à tous les deux,
j'ai bien essayé en changeant le Type TextBox en VBControlExtender mais VB ne veut pas (erreur type incompatible).
Même en travaillant avec le type Control, ça chibre qque part.
Peut-être faut-il créer une nouvelle classe avec les Events d'un control ?
Pis au lieu de faire Private WithEvents mTxt As TextBox, faire un Private WithEvents mTxt As MyClassWithEvents
@++
<hr width="100%" size="2" />
--Mortalino--
Le mystérieux chevalier, "Provençal, le Gaulois"
/DIV>
rvblog
Messages postés792Date d'inscriptionvendredi 4 mars 2005StatutMembreDernière intervention12 juin 20127 3 déc. 2006 à 14:40
Non, le problème n'est pas là,
Même si tu fais une classe de wrapping MyClassWithEvents, ce que faisait PCPT, tu ne pourras pas affecter à son membre de référence le contrôle indexé. Et c'est là que le bâs blesse!
rvblog<sup>n
Je veux ton bien....et je l'aurais....mieux vaut tard...que trop tard!</sup>
rvblog
Messages postés792Date d'inscriptionvendredi 4 mars 2005StatutMembreDernière intervention12 juin 20127 3 déc. 2006 à 15:03
Je viens par contre de refaire un petit test pour vérifier une idée.
Le test est concluant : on sait affecter une "référence à un contrôle utilisateur indexé" à une variable du même type, succeptible de récupérer les évènements, par contre, si ce même contrôle utilisateur est compilé (ou est contrôle utilisateur dans un autre projet du groupe), on ne sait plus le faire (on est pas forcé d'extrapoler en disant que c'est valable pour tous les contrôles AX, mais on peut le faire quand même)!
à+
rvblog<sup>n
Je veux ton bien....et je l'aurais....mieux vaut tard...que trop tard!</sup>
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 3 déc. 2006 à 19:04
salut rvblog,
encore parmis nous? ^^
ou peut-être prends-tu le forum à reculons
rhaaa, dès qu'on essayer de toucher aux infos cachées, on fini souvent.... beh on fini pas en fait
pour ton exemple "UC compilé ou non", on peut aussi se dire que la Classe TextBox (ou autre) est compilée (ce qui est vrai) et qu'elle serait aussi apte dans le cas contraire....
autrement dit, s'il y a une issue, elle n'est pas dans cette direction
ps : merci pour le RTB, j'aime assez le rendu .
"forum explorer"... (et ce qui en dépend et y est lié), pas le temps non.... tu finieras bien avant moi
++
<hr size="2" width="100%" />Prenez un instant pour répondre à ce sondage svp