代码之家  ›  专栏  ›  技术社区  ›  Zac

通过类触发控件的输入字段行为

  •  3
  • Zac  · 技术社区  · 7 年前

    我养了一只 query

    问题是我想使用的事件之一是 进入 进入 控件的事件?

    我尝试了班上大多数可用的活动,但没有一个按照我需要的方式进行。

    背景简介:我用 事件为中的字段设置帮助文本 集中 . 所以每次用户输入一个字段,我都会有一个帮助文本框,里面会填充帮助文本。

    我无法共享工作簿。

    3 回复  |  直到 6 年前
        1
  •  2
  •   Siddharth Rout    7 年前

    假设你的用户表单( 用户窗体1

    enter image description here

    我要示范一下 Enter Event TextBox ComboBox .

    确保将 CommandButton1 首先在用户窗体上。或者,设置为 TabIndex 0 . 这样,当用户窗体加载时,command按钮首先获得焦点,您可以测试 Entering 属于 文本框 .

    enter image description here

    将其粘贴到类模块中。我的班级模块名是 Class1

    Option Explicit
    
    Public WithEvents Usrfrm As UserForm1
    Const MyMsg As String = "Hiya there. Did you just try to sneak into the "
    
    Private Sub Usrfrm_OnEnter(ctrl As msforms.Control)
        Select Case True
            Case TypeName(ctrl) Like "ComboBox"
                'Call Usrfrm.Combobox_List(ctrl)
                MsgBox MyMsg & "combobox?", vbCritical, "Aha!"
            Case TypeName(ctrl) Like "TextBox"
                MsgBox MyMsg & "textbox?", vbCritical, "Aha!"
        End Select
    End Sub
    

    将此粘贴到用户表单代码区域

    Option Explicit
    
    Public Event OnEnter(ctrl As msforms.Control)
    Private prevCtl As msforms.Control
    Private mycls As Class1
    Private IsfrmUnloaded As Boolean
    
    Private Sub CommandButton1_Click()
        Unload Me
    End Sub
    
    Private Sub UserForm_Layout()
        Call spyWhatsGoingOn
    End Sub
    
    Private Sub spyWhatsGoingOn()
        Set mycls = New Class1
        Set mycls.Usrfrm = Me
    
        IsfrmUnloaded = False
    
        Set prevCtl = Me.ActiveControl
    
        RaiseEvent OnEnter(Me.ActiveControl)
    
        Do While IsfrmUnloaded = False
            If Not prevCtl Is Nothing Then
                If Not prevCtl Is Me.ActiveControl Then
                    RaiseEvent OnEnter(Me.ActiveControl)
                    Me.ActiveControl.SetFocus
                End If
            End If
            Set prevCtl = Me.ActiveControl
            DoEvents
        Loop
    End Sub
    

    enter image description here

        2
  •  1
  •   EvR    7 年前

    这是另一个解决方案(不适用于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事件都将被捕获,因此您必须相应地执行操作。

        3
  •  0
  •   Zac    7 年前

    所以我采用的方法是:我已经有了类模块 Change 事件( can be seen here ). 因为我没有机会 Enter 在我的课上,我用 KeyUp MouseDown

    推荐文章