如何在 initialization/activate 事件期间将焦点发送到 VBA 表单的文本框?

How to send focus to a text box of a VBA form during its initialization/activate event?

我在 Corel 中有一个 VBA 表格。行为与 Excel 中的类似行为完全相同... 最初,当表单初始化事件只包含一些代码行时,简单的结束行 me.txtCsv.Setfocus 用于将焦点发送到它上面。我的意思是,它似乎处于编辑模式,光标在里面闪烁。

一段时间后,应用程序变得复杂后,我无法将焦点发送到讨论中的文本框。

我知道 Activate 事件最后进行,我也有行 me.txtCsv.Setfocus。但没有预期的结果。在初始化事件代码中,我插入了那行 Debug.Print Me.ActiveControl.Name & " - 1",在许多地方将 1 in 2, 3 更改为 6,包括最后一行,并且讨论中的文本框名称 (txtCsv) 始终出现在 Immediate 中Window.

因此,讨论中的控件是激活控件,但加载表单时光标不在其中。

TabStop 设置为 True。我将 TabIndex 设置为 0.

控件已启用且未被阻止。我创建了一个包含三个文本框的新简单表单,效果很好。

我的意思是我要发送焦点的文本框在加载表单时具有焦点,在其 Initialize 或 Activate 事件中保留类似的代码。 我比较了两个表单和所有文本框控件的所有属性,它们是相同的...

当我从窗体上的另一个控件发送焦点时,讨论中的文本框收到它。

仅当显示窗体时它不再接收焦点,焦点由 Initialize 或 Activate 事件发送。

活动代码:

Private Sub UserForm_Activate()
    Me.txtCsv.SetFocus
End Sub
Private Sub UserForm_Initialize()
   Dim P As Printer, i As Long, NrImp As Long, prDefault As String, strJustEngr As String
   Dim Printers() As String, n As Long, s As String, boolFound As Boolean
   Dim strEng As String, MEngr As Variant, m As Variant, el As Variant, defSize As String
   Dim strDropbox As String

   boolOpt = True: boolFound = False
   Me.cbPrinters.Clear
    If Me.chkNewStyle.Value = True Then boolNewStyle = True

    prDefault = Application.Printers.Default.Name

    strEng = GetSetting(ECA_K, ECA_set, ECA_Engr, "No settings...")
    If strEng <> "No settings..." Then
        boolSelectedEngravers = True  ' only adding engraver is possible...
        MEngr = Split(strEng, "|")
        'Incarcare in combo:
        Me.cbPrinters.Clear
        For Each el In MEngr
            m = Split(el, ":")
            Me.cbPrinters.AddItem m(0)
            If m(0) = prDefault Then
                boolFound = True
                defSize = m(1)
            End If
        Next
        Me.cbPrinters.Value = Me.cbPrinters.List(0)
        With Me.btChoosePrinters
            .Caption = "Add an Engraver"
            .ControlTipText = "Add another Engraver(must be installed)" 
        End With
        Me.btEliminatePrinters.Enabled = True
        Me.lblPrinters.Caption = "Engravers: "
        Me.cbPrinters.ControlTipText = "Select Engraver to be used!"
    Else
        Printers = GetPrinterFullNames()
        For n = LBound(Printers) To UBound(Printers)
            Me.cbPrinters.AddItem Printers(n)
            If Printers(n) = prDefault Then boolFound = True
        Next n
        boolSelectedEngravers = False
    End If
    Debug.Print Me.ActiveControl.Name & " - 1"
    If boolFound Then
        Me.cbPrinters.Value = prDefault
    Else
        Me.lblStatus.Caption = "The default printer (""" & prDefault & """) is not a laser Engraver..."
    End If


    If GetSetting(ECA_K, ECA_set, "LowRAM", "No settings...") <> "No settings..." Then
        boolLowRAM = CBool(GetSetting(ECA_K, ECA_set, "LowRAM", "No settings..."))
    End If
    If boolLowRAM = True Then
        Me.chkLowRAM.Value = True
    Else
        Me.chkLowRAM.Value = False
    End If
    Debug.Print Me.ActiveControl.Name & " - 2"
    'Direct engrave setting:
    Dim strDirectEngrave As String
    strDirectEngrave = GetSetting(ECA_K, ECA_set, ECA_Direct_Engrave, "Nothing")
    If strDirectEngrave <> "Nothing" Then
        Me.chkDirectEngrave.Value = CBool(strDirectEngrave)
        If CBool(strDirectEngrave) = True Then
            boolDirectEngrave = True
        Else
            boolDirectEngrave = False
        End If
    End If
    '_______________________________________
    strJustEngr = GetSetting(ECA_K, ECA_set, ECA_Just_Engrave, "Nothing")
    If strJustEngr <> "Nothing" Then
        'Application.EventsEnabled = False
            boolChangeEngr = True
            Me.chkJustEngrave.Value = CBool(strJustEngr)
            boolChangeEngr = False
        'Application.EventsEnabled = True
        If CBool(strJustEngr) = True Then
            Me.chkDirectEngrave.Enabled = True
            boolJustEngrave = True
            Me.frLocFoldPath.Enabled = True
        Else
            Me.frLocFoldPath.Enabled = False
            Me.chkDirectEngrave.Enabled = False
        End If
    End If
    Debug.Print Me.ActiveControl.Name & " - 3"

    If boolSelectedEngravers Then
        Application.EventsEnabled = False
            Me.btGo.ForeColor = RGB(45, 105, 7)
            Me.txtCsv.BackColor = RGB(153, 255, 51)
            Me.btGo.Enabled = False
            Me.txtCsv.SetFocus
        Application.EventsEnabled = True
    End If
    strDropbox = GetSetting(ECA_K, ECA_set, ECA_Dropbox, "No value")
    If strDropbox <> "No value" Then
        If CBool(strDropbox) = True Then
            Me.chkDropbox.Value = True
        End If
    End If
    AllRefresh
    Me.chkCloseDoc.Value = True
    Me.txtCsv.SetFocus
    Debug.Print Me.ActiveControl.Name & " - 4"
End Sub
Private Sub AllRefresh()    
    Application.Optimization = False
    Application.EventsEnabled = True
    If Documents.Count > 0 Then
        ActiveWindow.Refresh
        ActiveDocument.PreserveSelection = True
    End If
    Application.Refresh
End Sub

你还有什么想测试的吗?

同时我又做了一些测试,分别是:

我创建了一个新项目(.GMS 文件)并在 discussion.I 中导入了表单,开始注释除最后两行代码之外的所有 Initialize 事件代码。

没有设置重点!注释所有内容,只允许 Activate 事件代码,它起作用了。

我开始在初始化事件代码中取消注释行,我发现有一行不允许将焦点发送到该文本框。

设置组合的值:Me.cbPrinters.Value = Me.cbPrinters.List(0),将其移动到 Activate 事件代码中,在指向 txtCSV 的部分之前,效果很好。

现在,我尝试以原始形式执行相同的操作,但它不起作用...

上述问题已通过先禁用再启用讨论中的文本框来解决,但仅在表单 Activate 事件 中这样做。它在 Initialize 事件中不起作用...

Private Sub UserForm_Activate()
    Me.txtCsv.Disable: Me.txtCsv.Enable
    Me.txtCsv.SetFocus
End Sub