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

VBA Discussion :

Interception des �v�nements Enter et Exit des contr�les MSForms.TextBox


Sujet :

VBA

  1. #1
    Membre tr�s actif Avatar de star
    Homme Profil pro
    .
    Inscrit en
    F�vrier 2004
    Messages
    949
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cor�e Du Nord

    Informations professionnelles :
    Activit� : .

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 949
    Par d�faut Interception des �v�nements Enter et Exit des contr�les MSForms.TextBox
    Bonjour,

    J'ai r�cup�r� en parti le code suivant sur le Web que j'essaye d'adapter afin d'intercepter les �v�nements Enter et Exit g�n�r�s par les contr�les MSForms.TextBox.

    J'ai le formulaire qui se charge et se referme convenablement, me semble-t-il. Ce qui me laisse � penser ne pas avoir de probl�mes particuliers de ce c�t�.

    Par contre mon probl�me est que je n'arrive pas � trapper les �v�nements Enter et Exit, malgr� le fait que le code provienne d'un exemple qui lui fonctionne tr�s bien (voir en pi�ce attach�e).

    La m�thode Initialize du formulaire fait appel au module de classe ci-dessous pour la gestion des �v�nements.

    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
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
     
    Option Explicit
     
    Private Type GUID
        Data1 As Long
        Data2 As Integer
        Data3 As Integer
        Data4(0 To 7) As Byte
    End Type
     
    #If VBA7 Then
        Private Declare PtrSafe Function IIDFromString Lib "ole32.dll" (ByVal lpsz As LongPtr, lpiid As GUID) As Long
        Private Declare PtrSafe Function ConnectToConnectionPoint Lib "shlwapi" Alias "#168" (ByVal punk As stdole.IUnknown, ByRef riidEvent As GUID, ByVal fConnect As Long, ByVal punkTarget As stdole.IUnknown, ByRef pdwCookie As Long, Optional ByVal ppcpOut As LongPtr) As Long
        Private Declare PtrSafe Function IsWindow Lib "user32" (ByVal hwnd As LongPtr) As Long
        Private Declare PtrSafe Function IUnknown_GetWindow Lib "shlwapi" Alias "#172" (ByVal pIUnk As IUnknown, ByVal hwnd As LongPtr) As Long
     
        Private hwnd As LongPtr
     
    #Else
        Private Declare Function IIDFromString Lib "ole32.dll" (ByVal lpsz As Long, lpiid As GUID) As Long
        Private Declare Function ConnectToConnectionPoint Lib "shlwapi" Alias "#168" (ByVal punk As stdole.IUnknown, ByRef riidEvent As GUID, ByVal fConnect As Long, ByVal punkTarget As stdole.IUnknown, ByRef pdwCookie As Long, Optional ByVal ppcpOut As Long) As Long
        Private Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As Long
        Private Declare Function IUnknown_GetWindow Lib "shlwapi" Alias "#172" (ByVal pIUnk As IUnknown, ByVal hwnd As Long) As Long
     
        Private hwnd As Long
     
    #End If
     
    Private WithEvents CmndBras  As CommandBars
     
    Private oClientForm As Object
    Private oCurrentTextBox As MSForms.TextBox
    Private sClassInstanceName As String
     
    Event OnEnter(ByVal TextBox As MSForms.TextBox)
    Event OnExit(ByVal TextBox As MSForms.TextBox, ByRef Cancel As MSForms.ReturnBoolean)
    Event BeforeUpdate(ByVal TextBox As MSForms.TextBox, ByRef Cancel As MSForms.ReturnBoolean)
    Event AfterUpdate(ByVal TextBox As MSForms.TextBox)
     
     
    ' __________________________________ CLASS PUBLIC METHOD ________________________________________
     
    Property Let HookEvents(ClassInstanceName As String, Optional ByVal TextBox As MSForms.TextBox, ByVal SetEvents As Boolean)
     
        Const S_OK = &H0
        Static lCookie As Long
        Dim tIID As GUID
     
        Debug.Print "HookEvents"
        If Not TextBox Is Nothing Then
            Debug.Print "HookEvents : Not TextBox Is Nothing"
            Set oCurrentTextBox = TextBox
            Debug.Print "HookEvents oCurrentTextBox = TextBox : " & oCurrentTextBox.Name
            Set oClientForm = GetUserForm(TextBox)
            sClassInstanceName = ClassInstanceName
            Debug.Print "HookEvents sClassInstanceName = ClassInstanceName : " & sClassInstanceName
     
            Set CmndBras = Application.CommandBars
            Call IUnknown_GetWindow(oClientForm, VarPtr(hwnd))
        End If
        If IIDFromString(StrPtr("{00020400-0000-0000-C000-000000000046}"), tIID) = S_OK Then
            If ConnectToConnectionPoint(Me, tIID, SetEvents, TextBox, lCookie) = S_OK Then
                Debug.Print oCurrentTextBox.Name & IIf(SetEvents, " connected", " disconnected") & " successfully"
            Else
                Debug.Print "Connection failed for: " & oCurrentTextBox.Name
            End If
        Else
            Debug.Print "HookEvents IIDFromString(StrPtr(""{00020400-0000-0000-C000-000000000046}""), tIID) = S_OK : False"
        End If
     
    End Property
     
    ' __________________________________ TEXTBOX CONTROL EVENTS ________________________________________
     
    Public Sub OnEnter()
        ' Attribute OnEnter.VB_UserMemId = &H80018202
        Dim oThis As ClassTextBoxEvents
        Set oThis = Me
        Call CallByName(oClientForm, sClassInstanceName, VbSet, oThis)
        Set oThis = Nothing
        Debug.Print "OnEnter oCurrentTextBox : " & oCurrentTextBox.Name
        RaiseEvent OnEnter(oCurrentTextBox)
    End Sub
     
    Public Sub OnExit(ByVal Cancel As MSForms.ReturnBoolean)
        ' Attribute OnExit.VB_UserMemId = &H80018203
        Debug.Print "OnExit oCurrentTextBox : " & oCurrentTextBox.Name
        RaiseEvent OnExit(oCurrentTextBox, Cancel)
    End Sub
     
    Public Sub BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
        ' Attribute BeforeUpdate.VB_UserMemId = &H80018201
        RaiseEvent BeforeUpdate(oCurrentTextBox, Cancel)
    End Sub
     
    Public Sub AfterUpdate()
        ' Attribute AfterUpdate.VB_UserMemId = &H80018200
        RaiseEvent AfterUpdate(oCurrentTextBox)
    End Sub
     
     
    ' __________________________________ PRIVATE ROUTINES ________________________________________
     
    Private Function GetUserForm(ByVal Ctrl As MSForms.Control) As Object
        Dim oTmp As Object
        Debug.Print "GetUserForm"
        Set oTmp = Ctrl.Parent
        Do While TypeOf oTmp Is MSForms.Control
            Set oTmp = oTmp.Parent
            Debug.Print "GetUserForm oTmp = oTmp.Parent : " & oTmp.Name
        Loop
        Set GetUserForm = oTmp
    End Function
     
    Private Sub CmndBras_OnUpdate()
        Debug.Print "CmndBras_OnUpdate"
        If IsWindow(hwnd) = 0 Then
            Debug.Print "CmndBras_OnUpdate IsWindow(hwnd) = 0 : " & IsWindow(hwnd)
            HookEvents(sClassInstanceName, oCurrentTextBox) = False
        End If
    End Sub
     
    Private Sub Class_Terminate()
        Debug.Print "Class instance treminated and memory released properly related to: " & oCurrentTextBox.Name
        Set oCurrentTextBox = Nothing
        Set oClientForm = Nothing
        Set CmndBras = Nothing
    End Sub

    Ci-dessous, la classe du formulaire.

    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
     
    Option Compare Database
    Option Explicit
     
    Private WithEvents tbx As ClassTextBoxEvents
     
    Private Sub UserForm_Initialize()
     
        Debug.Print "UserForm_Initialize FrmTabularEmployes"
     
        Dim frm As UserForm_FrmTabularEmployes
        Set frm = Me
     
        frm.Caption = "frm is an instance object of the UserForm_FrmTabularEmployes Class"
        Debug.Print "frm.Name : " & frm.Name
     
        Dim obj As Object
        Dim ctl As MSForms.Control
        Dim fld As MSForms.TextBox
     
        Dim lgNbreLignes As Long
        Dim intHeightLigne As Integer
        Dim intTopLeft As Integer
     
        lgNbreLignes = 4
        intHeightLigne = 20
        intTopLeft = 10
     
        Dim i As Long
        Dim j As Long
     
        j = 20
     
        For i = 0 To lgNbreLignes
            Set fld = frm.Controls.Add("Forms.TextBox.1", "fldTest" & i, True)
            j = j + intHeightLigne
            fld.Top = j
            fld.Left = intTopLeft
            fld.tag = i
            fld.Value = "fldTest" & i
        Next
     
        For Each ctl In frm.Controls
            If TypeOf ctl Is MSForms.TextBox Then
                Set tbx = New ClassTextBoxEvents
                tbx.HookEvents(ClassInstanceName:="tbx", TextBox:=ctl) = True
            End If
        Next ctl
     
        frm.ScrollBars = fmScrollBarsVertical
        frm.KeepScrollBarsVisible = fmScrollBarsNone
        frm.ScrollHeight = intHeightLigne * (lgNbreLignes + 3)
     
        With frm.Controls
            For i = 0 To .Count - 1
                If TypeName(.Item(i)) = "TextBox" Then
                    Debug.Print "frm.Controls.Item(" & i & ") : " & TypeName(.Item(i)); " " & VarType(.Item(i)) & " - Tag " & .Item(i).tag & " - Name " & .Item(i).Name & " - Value " & .Item(i).Value
                End If
            Next
        End With
     
        Debug.Print "Trace"
     
    End Sub
     
    Private Sub tbx_Change()
        Debug.Print "tbx_Change FrmTabularEmployes"
    End Sub
     
    Private Sub tbx_OnEnter(ByVal TextBox As MSForms.TextBox)
        Debug.Print "tbx_OnEnter FrmTabularEmployes"
    End Sub
     
    Private Sub tbx_OnExit(ByVal TextBox As MSForms.TextBox, Cancel As MSForms.ReturnBoolean)
     
        Debug.Print "tbx_OnExit FrmTabularEmployes"
     
        Debug.Print "ActiveControl : " & Me.ActiveControl.Name
        Debug.Print "UserForm_FrmTabularEmployes!fldTest1.Name : " & UserForm_FrmTabularEmployes!fldTest1.Name
     
        Dim tag As Long
        tag = Me.ActiveControl.tag + 1
     
        Debug.Print "tag : " & tag
        Debug.Print "Me.Controls.Item(" & tag & ").Name : " & Me.Controls.Item(tag).Name
        Me.Controls.Item(tag).SetFocus
     
    End Sub
     
    Private Sub tbx_BeforeUpdate(ByVal TextBox As MSForms.TextBox, Cancel As MSForms.ReturnBoolean)
        Debug.Print "tbx_OnEnter FrmTabularEmployes"
    End Sub
     
    Private Sub tbx_AfterUpdate(ByVal TextBox As MSForms.TextBox)
        Debug.Print "tbx_AfterUpdate FrmTabularEmployes"
    End Sub
    Vos contributions m'aideraient � comprendre pourquoi ce code ne fonctionne pas comme escompter.
    Merci d'avance
    .
    Pi�ce jointe 656542

  2. #2
    Invit�
    Invit�(e)
    Par d�faut
    Le module du class contient des propri�t�s internes pour attacher les fonctions � l'interface qui g�re l'evenement , il doit �tre import� et pas juste copier le code .

    deuxi�me note red�clarer le variable tbx comme public
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Private WithEvents tbx As ClassTextBoxEvents

  3. #3
    Membre tr�s actif Avatar de star
    Homme Profil pro
    .
    Inscrit en
    F�vrier 2004
    Messages
    949
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cor�e Du Nord

    Informations professionnelles :
    Activit� : .

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 949
    Par d�faut
    Bonjour Volid,
    Merci de ta r�ponse.
    Tu pr�cises
    Le module de class contient des propri�t�s internes pour attacher les fonctions � l'interface qui g�re l'�v�nement, il doit �tre import� et pas juste copier le code.
    Peux-tu me pr�ciser ce qui doit �tre import� au juste ?
    Est-ce le module de classe ou plut�t l'interface qui g�re l'�v�nement ?
    Merci d'avance
    .

  4. #4
    Invit�
    Invit�(e)
    Par d�faut
    A partir du fichier Excel qui fonctionne exporter le module de classe et enregistrez le dans un fichier et apr�s dans votre nouveau projet importer le fichier ( les deux op�rations sont possible via le menu principale ou contextuel)

    malheureusement y a pas moyens pour d�finir les DispID des m�thodes directement dans l'�diteur VBA
    Attribute OnEnter.VB_UserMemId = -2147384830
    Attribute OnExit.VB_UserMemId = -2147384829

    Le fichier export� "CTextBoxEvents.cls" donne le code suivant:

    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
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    VERSION 1.0 CLASS
    BEGIN
      MultiUse = -1  'True
    END
    Attribute VB_Name = "CTextBoxEvents"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = False
    Attribute VB_Exposed = False
    Option Explicit
     
    Private Type GUID
        Data1 As Long
        Data2 As Integer
        Data3 As Integer
        Data4(0 To 7) As Byte
    End Type
     
    #If VBA7 Then
        Private Declare PtrSafe Function IIDFromString Lib "ole32.dll" (ByVal lpsz As LongPtr, lpiid As GUID) As Long
        Private Declare PtrSafe Function ConnectToConnectionPoint Lib "shlwapi" Alias "#168" (ByVal punk As stdole.IUnknown, ByRef riidEvent As GUID, ByVal fConnect As Long, ByVal punkTarget As stdole.IUnknown, ByRef pdwCookie As Long, Optional ByVal ppcpOut As LongPtr) As Long
        Private Declare PtrSafe Function IsWindow Lib "user32" (ByVal hwnd As LongPtr) As Long
        Private Declare PtrSafe Function IUnknown_GetWindow Lib "shlwapi" Alias "#172" (ByVal pIUnk As IUnknown, ByVal hwnd As LongPtr) As Long
     
        Private hwnd As LongPtr
     
    #Else
        Private Declare Function IIDFromString Lib "ole32.dll" (ByVal lpsz As Long, lpiid As GUID) As Long
        Private Declare Function ConnectToConnectionPoint Lib "shlwapi" Alias "#168" (ByVal punk As stdole.IUnknown, ByRef riidEvent As GUID, ByVal fConnect As Long, ByVal punkTarget As stdole.IUnknown, ByRef pdwCookie As Long, Optional ByVal ppcpOut As Long) As Long
        Private Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As Long
        Private Declare Function IUnknown_GetWindow Lib "shlwapi" Alias "#172" (ByVal pIUnk As IUnknown, ByVal hwnd As Long) As Long
     
        Private hwnd As Long
     
    #End If
     
    Private WithEvents CmndBras  As CommandBars
    Attribute CmndBras.VB_VarHelpID = -1
     
    Private oClientForm As Object
    Private oCurrentTextBox As MSForms.TextBox
    Private sClassInstanceName As String
     
    Event OnEnter(ByVal TextBox As MSForms.TextBox)
    Event OnExit(ByVal TextBox As MSForms.TextBox, ByRef Cancel As MSForms.ReturnBoolean)
    Event BeforeUpdate(ByVal TextBox As MSForms.TextBox, ByRef Cancel As MSForms.ReturnBoolean)
    Event AfterUpdate(ByVal TextBox As MSForms.TextBox)
     
     
    ' __________________________________ CLASS PUBLIC METHOD ________________________________________
     
    Public Property Let HookEvents(ClassInstanceName As String, Optional ByVal TextBox As MSForms.TextBox, ByVal SetEvents As Boolean)
     
        Const S_OK = &H0
        Static lCookie As Long
        Dim tIID As GUID
     
        If Not TextBox Is Nothing Then
            Set oCurrentTextBox = TextBox
            Set oClientForm = GetUserForm(TextBox)
            sClassInstanceName = ClassInstanceName
     
            Set CmndBras = Application.CommandBars
            Call IUnknown_GetWindow(oClientForm, VarPtr(hwnd))
        End If
        If IIDFromString(StrPtr("{00020400-0000-0000-C000-000000000046}"), tIID) = S_OK Then
            If ConnectToConnectionPoint(Me, tIID, SetEvents, TextBox, lCookie) = S_OK Then
                'Debug.Print oCurrentTextBox.Name & IIf(SetEvents, " connected ", " disconnected") & " successfully."
            Else
                'Debug.Print "Connection failed for: " & oCurrentTextBox.Name
            End If
        End If
     
    End Property
     
    ' __________________________________ TEXTBOX CONTROL EVENTS ________________________________________
     
    Public Sub OnEnter() 
    Attribute OnEnter.VB_UserMemId = -2147384830
        'Attribute OnEnter.VB_UserMemId = &H80018202
        Dim oThis As CTextBoxEvents
        Set oThis = Me
        Call CallByName(oClientForm, sClassInstanceName, VbSet, oThis)
        Set oThis = Nothing
        RaiseEvent OnEnter(oCurrentTextBox)
    End Sub
     
    Public Sub OnExit(ByVal Cancel As MSForms.ReturnBoolean)
    Attribute OnExit.VB_UserMemId = -2147384829
        'Attribute OnExit.VB_UserMemId = &H80018203
        RaiseEvent OnExit(oCurrentTextBox, Cancel)
    End Sub
     
    Public Sub BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
    Attribute BeforeUpdate.VB_UserMemId = -2147384831
        'Attribute BeforeUpdate.VB_UserMemId = &H80018201
        RaiseEvent BeforeUpdate(oCurrentTextBox, Cancel)
    End Sub
     
    Public Sub AfterUpdate()
    Attribute AfterUpdate.VB_UserMemId = -2147384832
        'Attribute AfterUpdate.VB_UserMemId = &H80018200
        RaiseEvent AfterUpdate(oCurrentTextBox)
    End Sub
     
     
    ' __________________________________ PRIVATE ROUTINES ________________________________________
     
    Private Function GetUserForm(ByVal Ctrl As MSForms.Control) As Object
        Dim oTmp As Object
        Set oTmp = Ctrl.Parent
        Do While TypeOf oTmp Is MSForms.Control
            Set oTmp = oTmp.Parent
        Loop
        Set GetUserForm = oTmp
    End Function
     
    Private Sub CmndBras_OnUpdate()
        If IsWindow(hwnd) = 0 Then
            HookEvents(sClassInstanceName, oCurrentTextBox) = False
        End If
    End Sub
     
    Private Sub Class_Terminate()
        'Debug.Print "Class instance treminated and memory released properly related to: " & oCurrentTextBox.Name
        Set oCurrentTextBox = Nothing:  Set oClientForm = Nothing:  Set CmndBras = Nothing
    End Sub

  5. #5
    Membre tr�s actif Avatar de star
    Homme Profil pro
    .
    Inscrit en
    F�vrier 2004
    Messages
    949
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cor�e Du Nord

    Informations professionnelles :
    Activit� : .

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 949
    Par d�faut
    Merci Volid
    Apr�s application de tes indications, cela fonctionne parfaitement maintenant
    Encore merci
    .

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�ponses: 0
    Dernier message: 27/06/2024, 11h53
  2. Interception des erreurs sur un dbnavigator
    Par Jeepy dans le forum Bases de donn�es
    R�ponses: 1
    Dernier message: 16/05/2005, 16h59
  3. Interception des messages CLAVIER
    Par dede92 dans le forum Windows
    R�ponses: 10
    Dernier message: 03/03/2005, 17h47
  4. Interception des commandes in et out
    Par KDD dans le forum x86 16-bits
    R�ponses: 13
    Dernier message: 18/12/2002, 16h55
  5. [VB6] Interception des évènement Copier/Couper/Coller
    Par youtch dans le forum VB 6 et ant�rieur
    R�ponses: 5
    Dernier message: 18/10/2002, 17h09

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