Control Highlighting

The following example demonstrates how to handle the SetFocus event centrally in an application.  Open zip file

This project has two forms:  dlgDataEntry and dlgOptions.  dlgDataEntry is shown below:


fig1.  dlgDataEntry

In this image, the background of the Surname field is yellow.  As the user moves about the form using the tab key, or clicking on other fields, the field with the input focus is highlighted.

Most of the work is done in a class module, clsControlHighlighting.  The code for this class is below:

Option Explicit

Private WithEvents objmCbtEvents As CbtEvents
Private ctlmPreviousControl As Control

Public Sub SelectText(ByVal ctl As Control)
    ctl.SelStart = 0
    ctl.SelLength = Len(ctl.Text)
End Sub

Private Sub Class_Initialize()
    Set objmCbtEvents = ThisThread.CbtEvents
End Sub

Private Sub Class_Terminate()
    Set objmCbtEvents = Nothing
End Sub

Private Sub objmCbtEvents_SetFocus(Window As AkemiSpyLibrary.Window, 
  PreviousWindow As AkemiSpyLibrary.Window, Cancel As Boolean)
    Dim ctlActiveControl As Control
    
    'Find out which control is active.
    'Note that Screen.ActiveControl will return the previously
    'active control (which corresponds to PreviousWindow).  This is
    'because the SetFocus event handler is called prior to the event
    'being processed by VB.
    Set ctlActiveControl = FindControlFromWindow(Screen.ActiveForm, Window)
    
    If TypeName(ctlmPreviousControl) = "TextBox" Then
        ctlmPreviousControl.BackColor = vbWindowBackground
    End If
    
    If TypeName(ctlActiveControl) = "TextBox" Then
        ctlActiveControl.BackColor = &HC0FFFF
        SelectText ctlActiveControl
    End If
    
    Set ctlmPreviousControl = ctlActiveControl
End Sub

Private Function FindControlFromWindow(ByRef frm As Form, 
ByRef
 Window As AkemiSpyLibrary.Window) As Control
    'Return a reference to the control which corresponds to
    'the Window.
    Dim ctl As Control
    
    On Error Resume Next
    
    For Each ctl In frm.Controls
        'The following line will raise an error if the control does not
        'have an hWnd property.
        If ctl.hWnd = Window.hWnd Then
            Set FindControlFromWindow = ctl
            Exit Function
        End If
    Next ctl
    
    Set FindControlFromWindow = Nothing
End Function

The application only ever creates one instance of clsControlHighlighting.  This object in turn retrieves a CbtEvents object during its Initialize event. objmCbtEvents triggers a SetFocus event whenever the input focus moves from one control to another.

In this example, the CbtEvents object is retrieved using ThisThread.CbtEvents which means that it will only raise events triggered from within the application.

The project's main form is dlgDataEntry.  An instance of clsControlHighlighting is created during the form's load event.  The highlighting object remains active for the life-time of dlgDataEntry, even when another form is opened.

Option Explicit

'There is only one objmControlHighlighting object.
'Since dlgDataEntry is the main form for the project,
'the instance of clsControlHighlighting which
'is created in the form's load event will have the same
'life-time as the application.
Private objmControlHighlighting As clsControlHighlighting

Private Sub btnmCancel_Click()
   Unload Me
End Sub

Private Sub btnmOK_Click()
   Unload Me
End Sub

Private Sub btnmOptions_Click()
   dlgOptions.ShowvbModal
End Sub

Private Sub Form_Activate()
    'The following two lines force a SetFocus event when
    'the form is first opened so that txtmSurname will be
    'highlighted before the user has interacted with the
    'form.
    txtmGivenNames.SetFocus
    txtmSurname.SetFocus
End Sub

Private Sub Form_Load()
    Set objmControlHighlighting = New clsControlHighlighting
End Sub

Clicking on the "Options" button will bring up a second form, dlgOptions:


dlgOptions

The code for dlgOptions is below:

Option Explicit

Private Sub btnmCancel_Click()
   Unload Me
End Sub

Private Sub btnmOK_Click()
   Unload Me
End Sub

Private Sub Form_Activate()
    'The following two lines force a SetFocus event when
    'the form is first opened so that txtmOption1 will be
    'highlighted before the user has interacted with the
    'form.
    txtmOption2.SetFocus
    txtmOption1.SetFocus
End Sub

 

See also:  CbtEvents Class Reference

 

Home Copyright and Disclaimer