Как отправить фокус в текстовое поле формы VBA во время события инициализации / активации? - PullRequest
1 голос
/ 30 октября 2019

У меня есть форма VBA в Corel. Он ведет себя точно так же, как аналогичный в Excel ... Изначально, когда событие инициализации формы использовало только несколько строк кода, простая конечная строка me.txtCsv.Setfocus использовалась для отправки фокуса на него. Я имею в виду, что он находился в режиме редактирования, когда курсор мигает внутри.

Через некоторое время, после того, как приложение стало сложным, я не могу отправить фокус в текстовое поле в обсуждении.

Я знаю, что событие Activate идет последним, и у меня также есть строка me.txtCsv.Setfocus. Но без ожидаемого результата. Внутри кода события инициализации я вставил эту строку Debug.Print Me.ActiveControl.Name & " - 1", меняя 1 на 2, 3 на 6 во многих местах, включая последнюю строку и все время, когда имя текстового поля в обсуждении (txtCsv) появляется в Immediate Window.

Итак, обсуждаемый элемент управления является активированным , но курсор не находится внутри него, когда загружается форма.

TabStop установлен на True. Я установил TabIndex на 0.

Управление включено и не заблокировано. Я создал новую простую форму с тремя текстовыми полями, и она хорошо работает.

Я имею в виду текстовое поле, которое я хочу отправить фокусу, имеет фокус при загрузке формы, сохраняя аналогичный код в своемИнициализировать или активировать события. Я сравнил все свойства двух форм и всех элементов управления текстового поля, и они совпадают ...

Когда я отправляю фокус из другого элемента управления в форме, обсуждаемое текстовое поле получает его.

Он не получает фокус (больше) только при отображении формы, фокус отправляется с помощью функции Инициализация или Активация.

Код события:

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) иЯ импортировал форму в обсуждении. Я начал комментировать весь код события Initialize, кроме последних двух строк кода.

Фокус не был установлен! Комментируя все, разрешив только код события Activate, все заработало.

Я начал снимать комментарии в строке инициализации кода события и обнаружил строку, не позволяющую отправить фокус в это текстовое поле.

Установка значения комбо: Me.cbPrinters.Value = Me.cbPrinters.List(0), перемещение его в коде события Activate до того, как часть, указывающая на txtCSV, работала хорошо.

Теперь я попытался сделать то же самое в исходном видеи это не работает ...

...