ObjectCOM et héritage

Résolu
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 - 1 avril 2011 à 12:03
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 - 4 avril 2011 à 09:42
Bonjour,

Je voudrais crée un objet COM basé sur une classe DOT.NET déjà existante, mais sans avoir à modifier cette classe (je ne vais pas justifier du pourquoi je veut faire sa, mais sa se justifie ^^).

Je me suis donc dit : "J'hérite de la classe dans une autre classe com et poupouf sa fonctionneras ^^"

Bà non

Je comprend pas ? Pourtant c'est une classe tout ce qu'il y a de plus banale (enfin si elle à de fonction et procédure que je voudrais réutiliser dans VB6 mais rien exceptionnelle)

Le code de ma nouvelle classe :
<ComClass(VWConnexionCom.ClassId, VWConnexionCom.InterfaceId, VWConnexionCom.EventsId)> _
Public Class VWConnexionCom
    Inherits VWConnexion
#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "e1385565-1a54-4567-ac24-30613f1b60d2"
    Public Const InterfaceId As String = "6aad24a3-8060-479a-b94d-f1d1e1ec57b2"
    Public Const EventsId As String = "47862e54-75d7-4f7d-af82-36d0c6765666"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

End Class


Soit rien de rien juste un héritage

Mais du coup j'ai l'erreur :
Warning 1 'Microsoft.VisualBasic.ComClassAttribute' is specified for class 'VWConnexionCom' but 'VWConnexionCom' has no public members that can be exposed to COM; therefore, no COM interfaces are generated. E:\En développement\VW_ConnectionLib\VW_ConnectionLib\VWConnexionCom.vb 2 14 VW_ConnectionCom


Alors que ma classe "parent" contient un max de propriétés/fonctions/procédures public

Et en effet quand je compile et que veut l'utiliser dans VB6 je n'est aucune classe disponible

J'ai vraiment RIEN compris à l'héritage ou en effet ce truc devrais fonctionner ?

Admettons que je n'est rien compris comment fait-on pour crée ce genre de chose (sa m’étonnerais que sa ne soit pas possible quand même) ?

PS :
J'ai également tester d'hériter de cette classe :
Public Class Class1
    Public toto As Integer
End Class

J'ai exactement le même comportement

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo

23 réponses

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
1 avril 2011 à 14:00
Comme ça, je dirai qu'il te faudrait, pour le coté COM
redéclarer tes méthodes et propriétés...

et coller des appels à la classe MyBase soujacente...

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
3
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
1 avril 2011 à 14:23
Bonjour,

Ci-dessous un petit exemple pour illustrer ce que vous cherchez à faire.

Je réutilise notre fameux Workbook Excel, vus que nous avons vu la dernière fois comment il est constitué.

L'exemple est projet bibliothèque de classes. Pensez à cocher la case "Rendre l'assembly visible par COM" dans les informations d'assembly et de cocher "Inscrire pour COM Interp" dans la section Compiler de propriétés du projet.
La dernière option permet de faire automatiquement un tlbexp.exe et un regasm.exe lors de la compilation.

Imports System.Runtime.InteropServices
Imports Microsoft.Office.Interop

<ComVisible(True)> _
<Guid("A9FC804C-0EE6-4347-870D-F7CFCD7006D1")> _
Public Interface CustomWorkBook
    Inherits Excel.Workbook

    <ComVisible(True)> _
    <DispId(&H1000001)> _
    Sub ConsoleWriteCount()

End Interface

<ComVisible(True)> _
<Guid("81C96C5B-A24F-41FD-A4BF-2E65B38C67FB")> _
 _
<ClassInterface(ClassInterfaceType.None)> _
Public Class CustomWorkBookClass
    Inherits Excel.WorkbookClass
    Implements CustomWorkBook

    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub ConsoleWriteCount() Implements CustomWorkBook.ConsoleWriteCount
        Console.WriteLine("Mon classeur contient {0} feuilles", Me.Worksheets.Count)
    End Sub

End Class
3
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
1 avril 2011 à 14:29
Ok, donc c'est bien ca, faut se retaper toute l'interface...

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
3
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
1 avril 2011 à 14:30
arf donc si je comprend bien il vas falloir que je me re-cogne tous les appels à MyBase :/.
Puffff j'attendais mieux de l’héritage .

En tout cas merci pour vos réponses

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
0

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

Posez votre question
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
1 avril 2011 à 14:41
Oui, si VWConnexion n'est pas visible par COM, il faudra décrire toutes ses méthodes et autres dans l'interface.

Si VWConnexion était COM visible, la l'heritage aurait suffit.

Petite astuce pour Polack77. Si votre classe contient beaucoup de méthodes, avec un peut de System.Reflection et un bon algo, vous pouvez créer votre interface par code. ;)
0
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
1 avril 2011 à 15:20
Bà en faite je voulais surtout faire sa pour que les futures évolutions de la classe "parent" soit directement intégrer dans la classe "enfant" (et ce sans avoir à faire quoi que se soit, bon si recompiler mais c'est tout ). Mais si il faut que je redéclare toute les fonctions public à chaque fois c'est que sa ne répond pas à ma demande.

Je remarque juste que à chaque fois que je cherche à faire de l'héritage je tombe sur un cas spécifique (je fini par me demander si le cas générale existe réellement)

Sa vas finir par un copier coller violant et global de ma classe de base dans ma classe COM. Je gagnerais du temps. Et pour les évolutions, bà je referais un copier coller et puis c'est tout.

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
0
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
1 avril 2011 à 15:34
Je viens de tester de rendre visible par COM la classe VWConnexion. Et non, il faut quand même tout déclarer dans la classe héritière, si non sa marche pas coté VB6

L'héritage, c'est pas encore au point dans le VB.NET (enfin ce n'est que mon point de vue )

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
0
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
1 avril 2011 à 15:41
Juste pour être sur, votre classe "enfant" n'ajoute aucune méthode ou propriété à votre classe "parent" ?

Si je comprends bien, vous voulez juste que les deux classes aient les mêmes méthodes, mais qu'une soit COM visible. Ou suis-je à coté de la plaque ?

Car si c'est le cas, votre classe "enfant" n'a pas vraiment lieu d'être.

Vous pouvez très bien créer l'interface COM pour votre classe "parent" et utiliser votre classe dans du code .Net (par la classe) et dans du code VB6 (par l'interface).

Exemple (sans les attributs pour alléger):
Public Interface IVWConnexion
     Sub X()
     Sub Y()
End Interface

Public Class VWConnexion
   Implements IVWConnexion

   Public Sub X() Implement IVWConnexion.X
        ...
   End Sub

   Public Sub Y() Implement IVWConnexion.Y
        ...
   End Sub

End Class


Comme ca, si vous faite évoluer VWConnexion, il n'y aura au pire qu'a ajouter les nouvelles méthodes dans l'interface.

Dans tous les cas, une chose est sur, il faut que chaque entrée de la classe soit interfacée.
0
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
1 avril 2011 à 15:46
L'héritage, c'est pas encore au point dans le VB.NET


Ne confondez pas héritage et Interoperabilité.

Si votre classe de base n'est pas visible par COM, elle ne peut pas le devenir avec un simple héritage. Ce n'est pas le but de l'héritage.

Il faut bien que votre code non managé sache comment accéder à vos méthodes. Et c'est l'interface qui joue ce role.
0
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
1 avril 2011 à 15:51
Juste pour être sur, votre classe "enfant" n'ajoute aucune méthode ou propriété à votre classe "parent" ?

Si je comprends bien, vous voulez juste que les deux classes aient les mêmes méthodes, mais qu'une soit COM visible. Ou suis-je à coté de la plaque ?

En effet c'est ce que je veut faire. Enfin tout du moins pour le moment. Car je m'attend a avoir des modifications a faire dans la classe COM par la suite. Par exemple certain des événements de la classe "parent" envoie des exceptions (oui, oui, je remonte des exception par événement car ma classe "parent" permet des exécutions en multithreading donc pour faire remonté les erreurs je voie pas comment faire autrement). Je ne suis pas convaincu que je puise faire remonté ces événements tel quel au VB6 (quoi que ??? Je sait pas en faite )

Public Interface IVWConnexion
Sub X()
Sub Y()
End Interface

Public Class VWConnexion
Implements IVWConnexion

Public Sub X() Implement IVWConnexion.X
...
End Sub

Public Sub Y() Implement IVWConnexion.Y
...
End Sub

End Class

Et donc je peut déclarer une interface en COM ?
Ça sa serais pas mal

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
0
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
1 avril 2011 à 15:54
Ne confondez pas héritage et Interoperabilité.

Si votre classe de base n'est pas visible par COM, elle ne peut pas le devenir avec un simple héritage. Ce n'est pas le but de l'héritage.

J'ai tenté de rendre visible par COM ma classe parent et sa ne fonctionnais pas mieux (mais c'est possible que j'ai raté un épisode je ne suis pas encore totalement à l'aise avec l'héritage)

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
1 avril 2011 à 15:54
logiquement oui....

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
1 avril 2011 à 16:02
Haaaaa tiens Bà ques que j'ai foutu la 1ére fois
Je viens de faire ce test :
<ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _
Public Class ComClass1

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "e8663719-7f31-409f-9a68-7721d9386810"
    Public Const InterfaceId As String = "4080b332-d374-49a5-87b3-0b84b55026be"
    Public Const EventsId As String = "06c8c3f5-84fa-4715-97c1-73d40d6dfdd5"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub
    Public Function toto() As String
        Return "toto"
    End Function
End Class


ComClass(ComClass2.ClassId, ComClass2.InterfaceId, ComClass2.EventsId)> _
Public Class ComClass2
    Inherits ComClass1

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "02c536f1-badf-4a12-8f89-34e509041b1d"
    Public Const InterfaceId As String = "960cc08f-c520-4b13-ab11-81222ac81973"
    Public Const EventsId As String = "d26cb9aa-c428-40ec-91a5-1b7b31e5aec8"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

End Class


Et la fonction toto est bien visible depuis le VB6 en utilisant un objet basé sur ComClass2

Donc en effet foliv57 a effectivement raison

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
0
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
1 avril 2011 à 16:03
J'ai tenté de rendre visible par COM ma classe parent et sa ne fonctionnais pas mieux


Je vous remet l'exemple complet, mais sans l'héritage. Pensez surtout au 2 options que j'ai mentionné dans mon premier post.

Imports System.Runtime.InteropServices

<ComVisible(True)> _
<Guid("A9FC804C-0EE6-4347-870D-F7CFCD7006D1")> _
Public Interface IVWConnexion

    <ComVisible(True)> _
    <DispId(&H1000001)> _
    Sub MaSub()

    <ComVisible(True)> _
    <DispId(&H1000001)> _
    Function MaFonction() as Integer

End Interface

<ComVisible(True)> _
<Guid("81C96C5B-A24F-41FD-A4BF-2E65B38C67FB")> _
 _
<ClassInterface(ClassInterfaceType.None)> _
Public Class VWConnexion
    Implements IVWConnexion

    Public Sub New()
        ...
    End Sub

    Public Sub MaSub() Implements IVWConnexion.MaSub 
       ...  
    End Sub

    Public Function MaFonction() as Integer Implements IVWConnexion.MaFonction 
       Return 3  
    End Sub

End Class
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
1 avril 2011 à 16:10
qu'est-ce que j'ai foutu


un regasm entre-temps ?

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
1 avril 2011 à 16:53
Aller dernier post ensuite j’arrête de vous faire chi__

Suite a de multiple test je confirme que je ne peut pas faire remonter des événements contant des données de type "execption" (sa fait planté VB6), je m'y attendais.

Mon code :
Dans ma classe parent (que j'ai rendu visible par COM... Heeee c'est bien comme sa qu'on dit au moins ?)
''' <summary>
    ''' Informe qu'une erreur à été rencontré durant l'écriture asyncrone
    ''' </summary>
    ''' L&#8217;exception rencontrer


    ''' La requête qui à provoquer l&#8217;exception


    ''' <remarks></remarks>
    Public Event AsyncErreur(ByVal Ex As Exception, ByVal RequeteEnErreur As String)


Ma classe enfant :
<ComClass(VWConnexionCom.ClassId, VWConnexionCom.InterfaceId, VWConnexionCom.EventsId)> _
Public Class VWConnexionCom
    Inherits VWConnexion
#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "625a8a87-c87a-43f3-aef5-6b945d71318f"
    Public Const InterfaceId As String = "1eb34dbf-040d-4309-a444-66b94aba4597"
    Public Const EventsId As String = "3562c969-1da2-4e7c-b715-a1ecaf0c966b"
#End Region

#Region "Redéfinition(s)"
    Public Shadows Event AsyncErreur(ByVal Ex As Object, ByVal RequeteEnErreur As String)

    Private Sub VWConnexionCom_AsyncErreur(ByVal Ex As Exception, ByVal RequeteEnErreur As String) Handles MyBase.AsyncErreur
        RaiseEvent AsyncErreur(Ex, RequeteEnErreur)
    End Sub
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

End Class


Mon problème est que à partir du moment ou j'ajoute la région "Redéfinition(s)" le reste des propriétés et procédure qui étais visible ne le sont plus
Où est mon erreur svp ? (je regarderais plus en détail l'interface lundi, encore merci pour le bout de code foliv57 )

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
0
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
1 avril 2011 à 16:59
J'ai posté un peut vite
Même dans l’exemple de tout à l'heure
<ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _
Public Class ComClass1

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "e8663719-7f31-409f-9a68-7721d9386810"
    Public Const InterfaceId As String = "4080b332-d374-49a5-87b3-0b84b55026be"
    Public Const EventsId As String = "06c8c3f5-84fa-4715-97c1-73d40d6dfdd5"
#End Region

    Public Function toto() As String
        Return "toto"
    End Function
End Class

<ComClass(ComClass2.ClassId, ComClass2.InterfaceId, ComClass2.EventsId)> _
Public Class ComClass2
    Inherits ComClass1

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "02c536f1-badf-4a12-8f89-34e509041b1d"
    Public Const InterfaceId As String = "960cc08f-c520-4b13-ab11-81222ac81973"
    Public Const EventsId As String = "d26cb9aa-c428-40ec-91a5-1b7b31e5aec8"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

    Public Function toto2() As String
        Return "toto2"
    End Function

End Class


Ma fonction "toto" n'est plus visible dans VB6 pour un objet basé sur ComClass2 (seul toto2 est visible)

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
0
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
1 avril 2011 à 17:13
Personnellement, si je copie votre code, j'ai des avertissements sur les GUID dans ComClass2 car les variables entrent en conflit avec celles de ComClass1.

Votre problème vient peut-etre de la.

Pour les exceptions il faut que je jette un coup d'oeil dans mes archives si j'ai déjà traité le sujet. Mais c'est sur qu'elles ne sont pas native en VB6 donc pas pas évident.
0
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
1 avril 2011 à 17:19
J'ai modifier la comclass2 de la façon suivante :
<ComClass(ComClass2.ClassId2, ComClass2.InterfaceId2, ComClass2.EventsId2)> _
Public Class ComClass2
    Inherits ComClass1

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId2 As String = "02c536f1-badf-4a12-8f89-34e509041b1d"
    Public Const InterfaceId2 As String = "960cc08f-c520-4b13-ab11-81222ac81973"
    Public Const EventsId2 As String = "d26cb9aa-c428-40ec-91a5-1b7b31e5aec8"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

    Public Function toto2() As String
        Return "toto2"
    End Function

End Class


Mais le problème reste entier

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
0
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
1 avril 2011 à 17:23
Aller ras le bol sa attendras lundi.
Bon week-end (pas trop de bêtises, mais quand même un minimum, si non on finit par s’ennuyer)

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
0
Rejoignez-nous