IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Evènement d'une DLL C# utilisé en VB access 2003


Sujet :

C#

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Evènement d'une DLL C# utilisé en VB access 2003
    Bonjour, à tous.

    Je vous explique ce que je souhaite faire, alors je veux faire une dll écrite en C# (Visual Studio 2012)et l'utiliser en VB Access. Ma dll C# génère des évènements que je veux donc aussi utiliser en VB Access 2003.

    J'ai donc créé une dll exposé à COM avec une interface (pour pouvoir l'utiliser sur VB Access)et disposant d'évènement, que j'ai ensuite testé en console pour voir si la dll fonctionne avec les évènements. Puis la même dll sans les évènements pour tester cette dernière sur VB Access. Et d'après mes testes et ma compréhension cela fonctionne.

    Un peu de code pour voir ? (C'est le test console et le résultat est un affichage "C'est bon !!!" toutes les trois secondes)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Program
        {
            static void Main()
            {
                IMetronome m = new Metronome();
                m.Tick += new TickHandler(afficheEvent);
                m.Start();
     
            }
            private static void afficheEvent(object sender, ClassEventArgs e)
            {
                Console.WriteLine(e.MyEvent);
            }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public delegate void TickHandler(Metronome m, ClassEventArgs e);
     
        [ComVisible(true)]
        [Guid("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
        public interface IMetronome
        {
     
            event TickHandler Tick;
            void Start();
        }
     
        [Guid("936DA01F-9ABD-4d9d-80C7-02AF85C822A8")]
        public class Metronome : IMetronome
        {
            public event TickHandler Tick;
     
            public void Start()
            {
                while (true)
                {
                    System.Threading.Thread.Sleep(3000);
                    if (Tick != null)
                    {
                        ClassEventArgs e = new ClassEventArgs("c est bon !!");
                        Tick(this, e);
                    }
                }
            }
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class ClassEventArgs : EventArgs
        {
            private string myEvent = null;
     
            public ClassEventArgs(string theEventText)
            {
                if (theEventText == null) throw new NullReferenceException();
                myEvent = theEventText;
            }
     
            public string MyEvent
            {
                get { return this.myEvent; }
            }
        }
    Dans ma dll C# il y a les deux classes (Metronome et ClassEventArgs).

    Pour utiliser cette dll sur VB Access (sur un autre ordinateur), je génère un fichier .reg avec un RegAsm à partir du fichier dll.

    J'enregistre la dll à l'aide d'un gacutil -i.

    Et pour finir le fichier .tlb je l'ajoute dans les références du projet de VB Access, jusque là tout va bien.



    Maintenant je veux utiliser ma dll c# sur VB Access je fais alors:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim obj As IMetronome
    Set obj = New Metronome
    Et là c'est le drame je me retrouve avec un obj.add_Tick et un obj.remove_Tick, j'ai donc fait une supposition que .add_Tick correspond au += en C# et .remove_Tick au -= , cela permet de s'abonner et de se désabonner. Mais je n'arrive pas à les utiliser car je pense qu'il faut aussi créer une méthode qui va être appelé au moment de l'évènement.

    Je viens donc vers vous pour trouvez de l'aide sur l'utilisation de ces deux méthodes .add_Tick et .remove_Tick et pour création de la méthode qui va être appelée lors de l'évènement.

    Merci d'avance pour vos réponses, une question ? Nécessitez pas à me la poser.

  2. #2
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    Bonjour Rayzerger...
    La consommation d'un evenement manage par un client COM (en vb6 ou en vba)...est un peu plus complexe.
    Car il faut implementer une interface specifique additionnelle pour les evenements ...
    1/implementer l'interface normale ( methodes,props):IMetronome
    2/implementer un interface additionnelle IMetronomeEvents ( type InterfaceIsIDispatch) avec une methode:
    - ayant meme nom que l'event (declare dans ta classe)
    - meme signature que le delegue
    3/class Metronome:
    - implementer uniquement IMetronome
    - le decorer avec l'attribut [ComSourceInterfaces(typeof(IMetronomeEvents))]
    - declarer l'event Tick normalement
    - declarer une methode de declenchement d'evenement normale RaiseTickEvent avec meme signature que le delegue.....

    voici le code(suit) avec de petits changements:
    -eviter l'implementation explicite de IMetronome...
    Pour ne pas faire des appels à Metronome à liaison tardive(via interface)....
    -interface IMetronome de type "Dual"
    -class metronome doit etre decore egalement de [ClassInterface(ClassInterfaceType.AutoDual)]
    -le class ClassEventArgs doit etre public et implementé via un interface IClassEventArgs egalement "Dual"...et decore avec
    [ClassInterface(ClassInterfaceType.AutoDual)]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    using System;
    using System.Runtime.InteropServices;
     
    namespace LibComPerso
    {
     
        namespace EventSource
        {
            public delegate void TickHandler(Metronome m, ClassEventArgs ev);
     
            [Guid("9193939B-F470-4C34-B7BE-9F6824B9B221")]
            [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]
            public interface IMetronome
            {
                void Start();
            }
            // Step 1: Defines an event sink interface (IMetronomeEvents) to be     
            // implemented by the COM sink.
            [Guid("45304A07-1A80-4A59-B975-F2789E31C634")]
            [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
            public interface IMetronomeEvents
            {
                void Tick(Metronome m, ClassEventArgs ev);
     
            }
            // Step 2: Connects the event sink interface to a class 
            // by passing the namespace and event sink interface
            // ("EventSource.IMetronomeEvents, EventSrc").
            [ComVisible(true)]
            [Guid("90C6AB84-7302-4A2F-A1A4-A0C4336F7E51")]
            [ClassInterface(ClassInterfaceType.AutoDual)]
            [ComSourceInterfaces(typeof(IMetronomeEvents))]
            public class Metronome : IMetronome
            {
                public event TickHandler Tick;
                private int nbiter = 10; 
                public Metronome()
                {
                }
                #region IMetronome Membres
     
                public void Start()
                {
                    while (nbiter !=0)
                    {
                        System.Threading.Thread.Sleep(1000);
                        if (Tick != null)
                        {
                            ClassEventArgs e = new ClassEventArgs("c est bon !!");
                            Tick(this, e);
                        }
                        nbiter -= 1;
                    }
                }
     
                #endregion
     
                public void RaiseTickEvent(Metronome m, ClassEventArgs ev )
                {
                    Tick(m, ev);
                }
     
     
     
            }
        }
        //ClassEventArgs doit etre publie 
        [Guid("A01A1BA3-0559-4DCD-BCC4-F7A297D7A6CE")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]
        public interface IClassEventArgs
        {
            string MyEvent { get; }
        }
        [ComVisible(true)]
        [Guid("3876ACF1-75C7-4942-A397-E9D373B7ADCB")]
        [ClassInterface(ClassInterfaceType.AutoDual)]
        public class ClassEventArgs : EventArgs, IClassEventArgs
        {
            private string myEvent = string.Empty;
            public ClassEventArgs()
            { }
            public ClassEventArgs(string theEventText)
            {
                if (theEventText == null) throw new NullReferenceException("argument string null..");
                myEvent = theEventText;
            }
     
            #region IClassEventArgs Membres
     
            public string MyEvent
            {
                get { return this.myEvent; }
            }
     
            #endregion
        }
    }
    et le code vba pour appeler le metronome:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     
    'declare un class  avec des evenements
    Private WithEvents myClass As Metronome
    Private Sub CommandButton1_Click()
    Set myClass = New Metronome
    myClass.Start
     
    End Sub
    '  selectionner myClass dans la fenetre code(combox gauche)
    '  selectionner l'event Tick dans  la fenetre code(combox droit)
     
    Private Sub myClass_Tick(ByVal m As LibComPerso.Metronome, ByVal ev As LibComPerso.ClassEventArgs)
    TextBox1.Text = ev.MyEvent
     
    End Sub
    Dans l'explorateueur d'objets VBA tu peux voir comme les class appraissent avec un interface "Dual".....
    Par ailleurs referees -toi a ce topic MSDN Libray pour plus de profit:
    Comment : déclencher des événements gérés par un récepteur COM
    Pour réaliser une interopérabilité avec un récepteur d'événements COM
    Définissez l'interface du récepteur d'événements dans le code managé. Cette interface peut contenir un sous-ensemble des événements émis par une classe managée. Les noms des méthodes de l'interface doivent être identiques aux noms des événements.

    Appliquez l'attribut ComSourceInterfacesAttribute pour connecter l'interface du récepteur d'événements à la classe managée.

    Exportez l'assembly contenant la classe vers une bibliothèque de types. Utilisez Type Library Exporter, outil (Tlbexp.exe) ou une API équivalente pour exporter l'assembly.

    Implémentez l'interface du récepteur d'événements dans COM.

    Pour les clients COM qui réceptionnent des événements, implémentez l'interface du récepteur d'événements définie par la source de l'événement dans sa bibliothèque de types. Utilisez ensuite le mécanisme de point de connexion pour connecter l'interface du récepteur à la source de l'événement.
    bon code.....................

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Bonjour MABROUKI,
    Je te remercie pour ton aide, j'ai vais tester cela. T'es explications sont très claires, je te tiens au courant de mon développement.

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/03/2010, 18h56
  2. Codeguard dans une DLL utilisé par du code managé
    Par Volfoni dans le forum C++Builder
    Réponses: 0
    Dernier message: 06/11/2008, 17h06
  3. Comment utilisé une dll et la comprendre?
    Par alpha_one_x86 dans le forum Windows
    Réponses: 2
    Dernier message: 09/05/2008, 13h21
  4. Debug d'une DLL utilisé par un site ASP.Net
    Par vince_lille dans le forum ASP.NET
    Réponses: 8
    Dernier message: 06/03/2008, 14h38
  5. Réponses: 5
    Dernier message: 24/05/2006, 23h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo