Classe Objets (collection) avec la technique de _NewEnum (IUnknown)

Résolu
mortalino Messages postés 6786 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 décembre 2011 - 16 déc. 2006 à 03:25
mortalino Messages postés 6786 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 décembre 2011 - 16 déc. 2006 à 04:57
Salut à tous,

voici mon problème que j'ai depuis 2 semaines :

J'ai 3 classes qui me servent de collection Objets, j'arrive à ajouter ou supprimmer des objets, mais je galère sur l'énumération de ceux-ci (afin d'avoir leur nom).

Je vous ai simplifier le problème ici, bien entendu, j'ai changer l'attribut de la procédure NewEnum (de la dernière classe) avec l'ID passé à -4 et le membre masqué.

'__________________________________________________________________________
'__________________________________________________________________________
' Contenu de la Form ~frmZoomTest~

Option Explicit

Private Sub Form_Load()

' On instancie les coordonnées de la Form et de ses contrôles en vue du Zoom
    With sbMain
        Call .m_MyControls.AddAll(Me)  ' ajoute tout un tas de controls situé sur la Form
        MsgBox .m_MyControls.Count ' m'affiche 20
        Call .m_MyControls.Delete("VScroll1")
        MsgBox .m_MyControls.Count ' m'affiche 19
    End With
    
    Call test

End Sub

'__________________________________________________________________________
'__________________________________________________________________________
' Dans un Module

Option Explicit

Public PropertyZoom     As New FormZoomed_cls
Public sbMain           As New ListControls

'************************ Problème ************************
Sub test()
   Dim emp As MyControl
   
   MsgBox sbMain.m_MyControls.Count
   ' Ca c'est OK, j'ai bien le nombre (19, pour infos)
   
   For Each emp In sbMain.m_MyControls
   ' ici erreur 438
   ' l'objet ne gère pas cette propriété ou cette méthode
   
      MsgBox emp.ID & ", " & emp.Name
   Next
'********************** Fin Problème **********************
End Sub

'__________________________________________________________________________
'__________________________________________________________________________
' Contenu de la classe ~ListControls~

Option Explicit

Private mMyControls As New MyControls

Public Property Get m_MyControls() As MyControls
   Set m_MyControls =  mMyControls
End Property

'__________________________________________________________________________
'__________________________________________________________________________
' Contenu de la classe ~MyControl~

Option Explicit

Private mstrID As String

Property Get ID() As String
   ID = mstrID
End Property

Property Let ID(strNew As String)
      mstrID = strNew
End Property

'__________________________________________________________________________
'__________________________________________________________________________
' Contenu de la classe ~MyControls~

Option Explicit

Private mcolControls As New Collection

Public Sub Delete(ByVal Index As Variant)
   mcolControls.Remove Index
End Sub

' Méthodes de la classe Collection MyControl.

' celle-ci ajoute dans la classe collection TOUS les controls d'une Form
Public Function AddAll(ByVal oForm As Form) As MyControl
    Dim empNew As New MyControl, ctl As Control
    Static intEmpNum As Integer
    
        For Each ctl In oForm.Controls
            With empNew
                intEmpNum = intEmpNum + 1
                .Name = ctl.Name
                .ID = ctl.Name
                ' Ajoute la référence de l'objet MyControl à la
                ' collection, avec la propriété ID comme clé.
                mcolControls.Add empNew, .ID
                ' Renvoie une référence au nouvel objet MyControl.
                Set AddAll = empNew
            End With
        Next ctl
End Function

' Méthodes de la classe Collection MyControl.
Public Function Add(ByVal Name As String) As MyControl
   Dim empNew As New MyControl
   Static intEmpNum As Integer
   
   With empNew
      intEmpNum = intEmpNum + 1
      .Name = Name
      .ID = Name
      ' Ajoute la référence de l'objet MyControl à la
      ' collection, avec la propriété ID comme clé.
      mcolControls.Add empNew, .ID
   End With
   ' Renvoie une référence au nouvel objet MyControl.
   Set Add = empNew
End Function

Public Function Count() As Long
   Count = mcolControls.Count
End Function

Public Function Item(ByVal Index As Variant) As MyControl
   Set Item = mcolControls.Item(Index)
End Function

' NewEnum doit renvoyer l'interface IUnknown de
' l'énumérateur d'une collection.
Public Function NewEnum() As IUnknown
   Set NewEnum = mcolControls.[_NewEnum]
End Function

~ <small> Mortalino </small> ~

Tout ça pour savoir : comment parcourir tous les objets de la collection afin de lire chacun de leur nom ??
Pour ceux qui veulent tester, il suffit de mettre plusieurs controls sur la Form, non indexés, et il faut absolument un VScroll (nommé VScroll1).

Merci d'avoir lu et merci pour ceux qui pourront me répondre.

@++

<hr width ="100%" size="2" />
  --Mortalino--
Le mystérieux chevalier, "Provençal, le Gaulois"
/DIV>

5 réponses

mortalino Messages postés 6786 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 décembre 2011 18
16 déc. 2006 à 03:53
Décidémment, je devrais poster plus souvent, à chaque fois que je pose une question, je m'auto-répond 

En fait j'ai (avec mes moultes modifications / tests) loupé mon Attribut de la Procédure EnumVariant :
(comme quoi, sans ça, ça plante )

Menu Outils, Attribut de Procédures, choisir EnumVariant, Avancés >>, ID de la Procédure mettre -4, et cocher Masquer ce membre.

Voilà, c'était tout bête.

@++

<hr width="100%" size="2" />
  --Mortalino--
Le mystérieux chevalier, "Provençal, le Gaulois"
/DIV>
3
mortalino Messages postés 6786 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 décembre 2011 18
16 déc. 2006 à 03:55
Lire NewEnum au lieu de EnumVariant ^^

@++

<hr width="100%" size="2" />
  --Mortalino--
Le mystérieux chevalier, "Provençal, le Gaulois"
/DIV>
0
RicoNuch Messages postés 140 Date d'inscription mercredi 18 juin 2003 Statut Membre Dernière intervention 16 décembre 2006
16 déc. 2006 à 04:42
Je m'étonne quand même que ça marche vu que tu n'as pas défini la propriété Name dans ta classe MyControl.

D'autre part dans tes procédures "Add" tu entres la valeur "ctl.Name" pour les deux propriétés ID et Name, ce qui est un peu inutile.

En dernier lieu, dans ta procédure AddAll il faut instancier l'objet MyControl à chaque tour de boucle, sans quoi à la fin de la procédure ta collection est entièrement constituée du même objet dupliqué.
0
mortalino Messages postés 6786 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 décembre 2011 18
16 déc. 2006 à 04:55
Oui, concernant la propriété Name, c'était par rapport à mes tests, je l'ai supprimé 
Pour le AddAll, c'est transformé..

Public Function AddAll(ByVal oForm As Form) As MyControl
    Dim ctl As Control
    
        For Each ctl In oForm.Controls
            Call sbMain.MyControls.Add(ctl.Name)
        Next ctl
End Function

' Méthodes de la classe Collection MyControl.
Public Function Add(ByVal Name As String) As MyControl
   Dim empNew As New MyControl
   Static intEmpNum As Integer
   
   With empNew
      intEmpNum = intEmpNum + 1
      .Name = Name
      .ID = Name
      ' Ajoute la référence de l'objet MyControl à la
      ' collection, avec la propriété ID comme clé.
      mcolControls.Add empNew, .ID
   End With
   ' Renvoie une référence au nouvel objet MyControl.
   Set Add = empNew
End Function

Pour infos, c'est pour ma dernière source, qui vient d'être mise à jour

Merci pour tes conseils  ;)

@++

<hr width="100%" size="2" />
  --Mortalino--
Le mystérieux chevalier, "Provençal, le Gaulois"
/DIV>
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mortalino Messages postés 6786 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 décembre 2011 18
16 déc. 2006 à 04:57
Dans Add, j'ai pas virer le .Name mais fait comme si... (copier coller)

@++

<hr width="100%" size="2" />
  --Mortalino--
Le mystérieux chevalier, "Provençal, le Gaulois"
/DIV>
0
Rejoignez-nous