这是另一个解决方案(不适用于MAC)
保存它als CatchEvents.cls
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "CatchEvents"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
#If VBA7 And Win64 Then
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
#Else
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
#End If
Private EventGuide As GUID
Private Ck As Long
Private ctl As Object
'All Other Control-Events also possible
Public Sub MyEnter()
Attribute MyEnter.VB_UserMemId = -2147384830
Select Case TypeName(ctl)
Case "TextBox": MsgBox "Your code for " & ctl.Name & " here!"
Case Else: MsgBox "You entered no TextBox but another control (" & ctl.Name & ")!"
End Select
End Sub
Public Sub ConnectAllEvents(ByVal Connect As Boolean)
With EventGuide
.Data1 = &H20400
.Data4(0) = &HC0
.Data4(7) = &H46
End With
ConnectToConnectionPoint Me, EventGuide, Connect, ctl, Ck, 0&
End Sub
Public Property Let Item(Ctrl As Object)
Set ctl = Ctrl
Call ConnectAllEvents(True)
End Property
Public Sub Clear()
If (Ck <> 0) Then Call ConnectAllEvents(False)
Set ctl = Nothing
End Sub
在VBA编辑器中导入此文件
在您的Userform代码中添加:(当您已经有一个初始化事件时,可以将这些事件组合起来)
Private AllControls() As New CatchEvents 'on top
Private Sub UserForm_Initialize()
ReDim AllControls(Controls.Count - 1)
For j = 0 To Controls.Count - 1
AllControls(j).Item = Controls(j)
Next
End Sub
现在,任何控件的每个Enter事件都将被捕获,因此您必须相应地执行操作。