VB6 Capturing the Tab Key



我正在vb6中制作一个exe,该窗体可供用户填写。我试图使它,如果你Tab过去的表单的可见区域,它会自动向下滚动,如果你的ActiveControl不是在表单的可见部分。我唯一的问题是,我找不到一种方法来捕捉Tab键。正如我在谷歌搜索后所理解的那样,捕获tab键的一种方法是将窗体的KeyPreview属性设置为True,并将窗体上的每个控件的TabStop属性设置为false。

我的问题是,如果有任何方法来捕获Tab键在vb6而不必禁用所有的TabStops。

尝试查看不同的属性如何?

当控件"进入"事件被触发时,可以读取帮助您确定向下滚动吗?这应该在用户选择每个项目时发生,并允许您决定在哪里滚动视图。

我想我有一个答案,但它是未经测试的。

使用计时器控件,获得活动控件。然后看看表单的Top &与活动控件的高度属性相比,您可以确定活动控件是否在窗体的可见区域内,如果需要,可以滚动窗体。

希望能有所帮助。

当有控件可以获得焦点时,在VB6表单中(使用本机方法)无法捕获Tab按下。

但是,您可以使用其他方法,如计时器检查当前控件或捕获GotFocus事件。这些还将处理其他获得焦点的方式,如访问键或简单的鼠标点击。

这可能不是一个完整的答案,但有几个例子如何绕过这个问题在vbforums:http://www.vbforums.com/showthread.php?231180-VB-A-demonstration-of-how-to-trap-the-Tab-key

以编程方式扫描表单上的控件。

注意那些TabStop=True的

将它们放入按TabIndex排序的列表中

清除所有控件的TabStop=True属性。

打开表单的KeyPreview选项

捕捉表单的_KeyDown事件

如果键是tab键,遍历控制列表找到下一个或上一个键,并将焦点设置在该键上。

如果焦点在网格上,您可以选择向前或向后移动所选的Row/Col。

我早在石器时代就写了这个类。丑陋得可耻的代码,但它可以工作。

带有多个控件和一个网格的表单:

Private WithEvents TabStop As cTabStop
Private Sub Form_Load()
    Me.MSFlexGrid1.Rows = 3
    Me.MSFlexGrid1.Cols = 3
    Me.MSFlexGrid1.FixedRows = 0
    Me.MSFlexGrid1.FixedCols = 0
    Set TabStop = New cTabStop
    TabStop.Setup Me
End Sub
Private Sub TabStop_TabPressed(ByVal Shift As Integer, Cancel As Integer)
    If Me.ActiveControl.Name = Me.MSFlexGrid1.Name Then
        If Shift = 0 Then
            If Me.MSFlexGrid1.Col < Me.MSFlexGrid1.Cols - 1 Then
                Me.MSFlexGrid1.Col = Me.MSFlexGrid1.Col + 1
                Cancel = 1
            ElseIf Me.MSFlexGrid1.Row < Me.MSFlexGrid1.Rows - 1 Then
                Me.MSFlexGrid1.Col = 0
                Me.MSFlexGrid1.Row = Me.MSFlexGrid1.Row + 1
                Cancel = 1
            End If
        Else
            If Me.MSFlexGrid1.Col > 0 Then
                Me.MSFlexGrid1.Col = Me.MSFlexGrid1.Col - 1
                Cancel = 1
            ElseIf Me.MSFlexGrid1.Row > 0 Then
                Me.MSFlexGrid1.Col = Me.MSFlexGrid1.Cols - 1
                Me.MSFlexGrid1.Row = Me.MSFlexGrid1.Row - 1
                Cancel = 1
            End If
        End If
    End If
End Sub
类:

Option Explicit
' ------------------------------------------------------------------------------
' This class ATTEMPTS to manage Tab Keypress events
' The specific advantage is the ability capture and cancel a Tab Keypress
'
' This is a horribly inelegant way to get the job done
'
' Bug:
' If a control should be next to receive focus, but is sitting on a control
' which is hidden, the tab order will not be able to proceed past that control.
' i.e. Command1 on Frame1 where Frame1.Visible = False
' ------------------------------------------------------------------------------
Private Type typeControl
    Control     As Control
    TabIndex    As Long
End Type
Private Type typeSettings
    Controls()      As typeControl
    ControlCount    As Long
End Type
Public Event TabPressed(ByVal Shift As Integer, ByRef Cancel As Integer)
Private Settings As typeSettings
Private WithEvents Form As Form
Public Sub Setup(Form_ As Form)
    Call FunctionTagger("cTabStop", "Setup")

    On Error GoTo E
    Dim Control As Control
    ' Get the Form and enable its KeyPreview ability
    Set Form = Form_
    Form.KeyPreview = True
    ' Get the Tab-Able controls from the form
    Settings.ControlCount = 0
    ReDim Settings.Controls(0 To 0)
    For Each Control In Form.Controls
        Call AddControl(Control)
    Next Control
    Exit Sub
E:
    Debug.Print " " & Err.Description
End Sub
Public Sub Clear()
    Call FunctionTagger("cTabStop", "Clear")

    Set Form = Nothing
    Settings.ControlCount = 0
    ReDim Settings.Controls(0 To 0)
End Sub
Private Sub AddControl(ByRef Control As Control)
    Call FunctionTagger("cTabStop", "AddControl")
    On Error GoTo E
    Dim TabIndex    As Long
    Dim TabStop     As Boolean
    Dim Visible     As Boolean
    Dim Enabled     As Boolean
    ' Only accept controls with these four properties
    TabStop = Control.TabStop
    TabIndex = Control.TabIndex
    Visible = Control.Visible
    Enabled = Control.Enabled
    ' Diable the control's TabStop property
    Control.TabStop = False
    ' Add the control to our list
    Settings.ControlCount = Settings.ControlCount + 1
    ReDim Preserve Settings.Controls(0 To Settings.ControlCount - 1)
    Set Settings.Controls(Settings.ControlCount - 1).Control = Control
    Settings.Controls(Settings.ControlCount - 1).TabIndex = TabIndex
    Exit Sub
E:
End Sub
Private Sub Class_Initialize()
    Call FunctionTagger("cTabStop", "Class_Initialize")

    Clear
End Sub
Private Sub Class_Terminate()
    Call FunctionTagger("cTabStop", "Class_Terminate")

    Clear
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Call FunctionTagger("cTabStop", "Form_KeyDown")

    Dim Cancel As Integer
    If KeyCode = 9 Then
        KeyCode = 0
        RaiseEvent TabPressed(Shift, Cancel)
        Debug.Print " Tab Pressed"
        If Cancel <> 0 Then     ' Tab Keypress Cancelled...
            KeyCode = 0
        ElseIf Shift = 0 Then   ' Tab Pressed...
            TabRight
        ElseIf Shift = 1 Then   ' Shift-Tab Pressed...
            TabLeft
        End If
    End If
End Sub
Public Sub TabLeft()
    Call FunctionTagger("cTabStop", "TabLeft")

    On Error GoTo E
    Dim CurTabIndex     As Long
    Dim NextControl     As Long
    Dim NextTabIndex    As Long
    Dim c               As Long
    ' Get the Tab Index of the currently active control
    If Not Form.ActiveControl Is Nothing Then ' 2012-09-25 - Jaron
        CurTabIndex = Form.ActiveControl.TabIndex
    End If
    ' Find the control with the next smallest Tab Index
    NextControl = -1
    NextTabIndex = -1
    For c = 0 To Settings.ControlCount - 1
    '        With Settings.Controls(c) ' 2007-05-07
            If Settings.Controls(c).TabIndex >= NextTabIndex And Settings.Controls(c).TabIndex < CurTabIndex Then
                If Settings.Controls(c).Control.Visible And Settings.Controls(c).Control.Enabled Then
                    NextControl = c
                    NextTabIndex = Settings.Controls(c).TabIndex
                End If
            End If
    '        End With
    Next c
    ' Set focus to the next control
    If NextControl >= 0 Then
    '        With Settings.Controls(NextControl).Control ' 2007-05-07
            'Debug.Print " Set Focus to " & Settings.Controls(NextControl).Control.Name
            SetFocusSafe Settings.Controls(NextControl).Control ' 2007-06-05
            DoEvents
    '        End With
    End If
    Exit Sub
E:
    Debug.Print " " & Err.Description
End Sub
Public Sub TabRight()
    Call FunctionTagger("cTabStop", "TabRight")

    On Error GoTo E
    Dim CurTabIndex     As Long
    Dim NextControl     As Long
    Dim NextTabIndex    As Long
    Dim c               As Long
    ' Get the Tab Index of the currently active control
    If Not Form.ActiveControl Is Nothing Then ' 2012-09-25 - Jaron
        CurTabIndex = Form.ActiveControl.TabIndex
    End If
    ' Find the control with the next largest Tab Index
    NextControl = -1
    NextTabIndex = 999999999
    For c = 0 To Settings.ControlCount - 1
    '        With Settings.Controls(c) ' 2007-05-07
            If Settings.Controls(c).TabIndex <= NextTabIndex And Settings.Controls(c).TabIndex > CurTabIndex Then
                If Settings.Controls(c).Control.Visible And Settings.Controls(c).Control.Enabled Then
                    NextControl = c
                    NextTabIndex = Settings.Controls(c).TabIndex
                End If
            End If
    '        End With
    Next c
    ' Set focus to the next control
    If NextControl >= 0 Then
    '        With Settings.Controls(NextControl).Control ' 2007-05-07
            'Debug.Print " Set Focus to " & Settings.Controls(NextControl).Control.Name
            SetFocusSafe Settings.Controls(NextControl).Control ' 2007-06-05
            DoEvents
    '        End With
    End If
    Exit Sub
E:
    Debug.Print " " & Err.Description
End Sub
' ------------------------------------------------------------------------------
Private Sub SetFocusSafe(ByRef Control As Control)
    On Error GoTo E
    Control.SetFocus
    Exit Sub
E:
End Sub
Private Sub FunctionTagger(ByVal sModule As String, ByVal sFunction As String)
    Debug.Print " " & Time$ & " " & sModule & "." & sFunction
End Sub
' ------------------------------------------------------------------------------
' ------------------------------------------------------------------------------

最新更新