1

我正在 vb6 中制作一个 exe,其中包含供用户填写的表格。我正在尝试这样做,以便如果您 Tab 越过表单的可见区域,如果您的 ActiveControl 不在表单的可见部分中,它将自动为您向下滚动。我唯一的问题是我找不到捕获 Tab 按键的方法。正如我在经过多次谷歌搜索后了解到的那样,捕获 tab 键的一种方法是将表单的 KeyPreview 属性设置为 True 并将 TabStop 属性设置为 false 对于表单上的每个控件。

我的问题是是否有任何方法可以在 vb6 中捕获 Tab 按键,而不必禁用所有 TabStop。

4

5 回答 5

1

You can not capture the Tab press in a VB6 form (using native methods) when there are controls that can get focus.

You can however user other methods like a timer checking the current control or capturing the GotFocus events. These will also handle other ways of getting focus liek access keys or simply mouse clicking.

于 2013-06-21T13:31:33.163 回答
1

我想我有一个答案给你,但它未经测试。

使用计时器控件,获取活动控件。然后查看窗体的 Top & Height 属性,与活动控件相同,可以判断活动控件是否在窗体的可视区域内,如果需要滚动窗体。

希望能帮助到你。

于 2013-06-21T04:38:43.967 回答
1

尝试查看不同的属性怎么样?

当控件“进入”事件被触发时阅读可以帮助您确定向下滚动吗?这应该在用户通过每个项目进行选项卡时发生,并且可以让您确定滚动视图的位置。

于 2013-06-21T01:22:36.223 回答
0

这可能不是您问题的完整答案,但有几个示例说明如何在 vbforums 上解决此问题: http ://www.vbforums.com/showthread.php?231180-VB-A-demonstration-of -如何捕获 Tab 键

于 2013-06-21T13:18:24.487 回答
0

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

注意那些有 TabStop=True 的。

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

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

打开表单的 KeyPreview 选项。

捕获表单的 _KeyDown 事件。

如果键是 Tab 键,则通过控制列表单步查找下一个或上一个并设置焦点。

如果焦点位于网格上,您可以选择向前或向后移动选定的行/列。

我在石器时代写了这门课。可耻的丑陋代码,但它有效。

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

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

' ------------------------------------------------------------------------------
' ------------------------------------------------------------------------------
于 2017-07-24T22:47:48.117 回答