Change border color of textboxes when they have focus (1 Viewer)

Richard1980

Registered User.
Local time
Tomorrow, 00:18
Joined
Aug 13, 2012
Messages
72
Hello guys,
no problem about setting a different border color for a single textbox (or combobox or listbox) which has focus. How about to change, with a small and fast VBA code avoiding to write code for each textbox, the border color (ora other textbox properties) for a many controls in a form?
I tried using 'For each ctrl in Form....', but I got only bad results. All my control are within differente pages in TAB control.
Thansk, Bye.

Riccardo
 

boblarson

Smeghead
Local time
Today, 15:18
Joined
Jan 12, 2001
Messages
32,059
What version of Access are you using? You should be able to use CONDITIONAL FORMATTING as there is a selection which is instead of VALUE IS to CONTROL HAS FOCUS.
 

Richard1980

Registered User.
Local time
Tomorrow, 00:18
Joined
Aug 13, 2012
Messages
72
I have MS Access 2010 and no, conditional formatting doesn't have choice about border color or border width.
 

boblarson

Smeghead
Local time
Today, 15:18
Joined
Jan 12, 2001
Messages
32,059
I have MS Access 2010 and no, conditional formatting doesn't have choice about border color or border width.

So, you want the border color and width to be changed for text boxes, list boxes and combo boxes? And do you want the one that has the focus to be the one changed or do you mean all at the same time?

And just some info for you - controls on different tabs are still just controls on the same form. If you have SUBFORMS on the different tabs then that has to be taken into account. Otherwise you just refer to the controls as if there were no tab control.
 

Richard1980

Registered User.
Local time
Tomorrow, 00:18
Joined
Aug 13, 2012
Messages
72
Exectly. I want the textbox having focus changes its border color (or even its width), only the textbox focused. Then, when it loses the focus its border color returns to the default one.
I have just tried with this code, but get errors:
Code:
Private Form_Load()
Dim ctl As Control
Dim frm As Form

For each ctl in frm
ctl.ongotfocus = ctl.bordercolor = RGB (XXX,XXX,XXX)
ctl.onlostfocus = ctl.bordercolor = RGB (XXX,XXX,XXX)
Next ctl
End sub
I am sure the problem is in "For Each ..." section and probably in the event type of the Form.
 
Last edited:
  • Like
Reactions: agh

boblarson

Smeghead
Local time
Today, 15:18
Joined
Jan 12, 2001
Messages
32,059
Exectly. I want the textbox having focus changes its border color (or even its width), only the textbox focused. Then, when it loses the focus its border color returns to the default one.
I have just tried with this code, but get errors:
Code:
Private Form_Load()
Dim ctl As Control
Dim frm As Form
 
For each ctl in frm
ctl.ongotfocus = ctl.bordercolor = RGB (XXX,XXX,XXX)
ctl.onlostfocus = ctl.bordercolor = RGB (XXX,XXX,XXX)
Next ctl
End sub
I am sure the problem is on For Each section and probably in the event type of the Form.

Okay first off you would need to use
For Each ctl in frm.CONTROLS

or did you just accidentally omit it in the code you posted here?

Second, your reference to set them is not right.

What I would do is create a Function like this in a standard module:

Code:
Function SetFocusCtl(strFrm As String, strCtlNameWithFocus As String, blnFocus As Boolean)
    Dim strActiveColor As String: strActiveColor = RGB(255, 0, 0)
    Dim strNonActiveColor As String: strNonActiveColor = RGB(0, 0, 0)
    Const intActiveWidth As Integer = 3
    Const intNonActiveWidth As Integer = 1
    Dim ctl As Control
    Dim frm As Form
 
    Set frm = Forms(strFrm)
 
    For Each ctl In frm.Controls
        Select Case ctl.ControlType
        Case acTextBox, acComboBox, acListBox, acOptionGroup
            If ctl.Name = strCtlNameWithFocus Then
                ctl.BorderColor = strActiveColor
                ctl.BorderWidth = intActiveWidth
            Else
                ctl.BorderColor = strNonActiveColor
                ctl.BorderWidth = intNonActiveWidth
            End If
        End Select
    Next ctl

End Function

And then in the form's On Load event Or Open event:

Code:
Private Sub Form_Load()
    Dim ctl As Control
    Dim strGot As String
    Dim strLost As String

    
    For Each ctl In Me.Controls
        Select Case ctl.ControlType
        Case acTextBox, acComboBox, acListBox, acOptionGroup
            With ctl
            strGot = "=SetFocusCtl([Form].[Name],[" & ctl.Name & "].[Name], True)"
            strLost = "=SetFocusCtl([Form].[Name],[" & ctl.Name & "].[Name], False)"
                .OnGotFocus = strGot
                .OnLostFocus = strLost
            End With
        End Select
    Next
End Sub
 

Richard1980

Registered User.
Local time
Tomorrow, 00:18
Joined
Aug 13, 2012
Messages
72
Thanks Bob, it works perfectly, but I must admit I cannot understand many things in the code. I need to study it deeply.
Bye.
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 23:18
Joined
Sep 12, 2006
Messages
15,660
i am messing with this at present

one issue i found is that in some cases access does not actually use the colors you think it does - it actually uses colors from a default "theme" pallette - which are not the same as the colours.

I just checked - it depends whether you use windows themed controls or not - which is an access option- so maybe your code needs to allow for both possibilities.

so change a border from an initial black ( 0 = vbblack ) to say vbred, and then back again, and it will look different to what it did originally.

i also have real difficulties managing the appearance of check boxes, and option buttons.

finally in a continuous form, you have to go to conditional formatting - and unfortunately there is no control border setting for a conditional format.

Still trying though!
 

ChrisO

Registered User.
Local time
Tomorrow, 08:18
Joined
Apr 30, 2003
Messages
3,202
By only passing the Control, the code can be reduced a bit.
The Control is unique so we don’t need to pass the Form to the HandleFocus Function.

Each Control will need “HighlightOnFocus” in its Tag property.

In a standard module:-
Code:
Public Function SetFocusHandlers(ByRef frm As Form)
    Dim ctl As Control

    For Each ctl In frm
        If ctl.Tag = "HighlightOnFocus" Then
            ctl.OnGotFocus = "=HandleFocus([" & ctl.Name & "], True)"
            ctl.OnLostFocus = "=HandleFocus([" & ctl.Name & "], False)"
        End If
    Next
    
End Function


Public Function HandleFocus(ByRef ctl As Control, ByVal blnFocus As Boolean)
 
    If blnFocus = True Then
        ctl.BorderColor = RGB(255, 0, 0)
        ctl.BorderWidth = 3
    Else
        ctl.BorderColor = RGB(0, 0, 0)
        ctl.BorderWidth = 1
    End If

End Function


Behind the Form:-
Code:
Private Sub Form_Load()

    SetFocusHandlers Me

End Sub

Chris.
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 23:18
Joined
Sep 12, 2006
Messages
15,660
bob/chris

thanks for the ideas. very ingenious.

i assumed iterating all the controls every time was a bit inefficient, but it doesn't seem to take long.

can you do this in an mde/accde as well?

----
note that in both cases i changed the event to enter/exit, as option groups don't have a gotfocus/lostfocus (at least not in A2003)

also checkboxes, and controls that aren't flat (eg sunken) don't show the border, but do lose the windows theme setting while they have the focus,
 

ChrisO

Registered User.
Local time
Tomorrow, 08:18
Joined
Apr 30, 2003
Messages
3,202
Dave.

Yes it can be done in an mde and I don’t really care if it can’t be done in an accde.
If it can’t be done in an accde then that’s Microsoft’s stuff up, not mine.

As for all the rest, it is just a matter of writing to code to do it. If the border of Sunken Text Boxes can’t be highlighted then don’t try to do it. If it’s important then create a rectangle around those controls and highlight the rectangle.

The first thing is imagination and then comes the coding skills to do it.
For example (and many people don’t see it), that’s what Stephen Lebans site is all about… imagination.
The rest is just the coding skills to do it.

Chris.
 

Richard1980

Registered User.
Local time
Tomorrow, 00:18
Joined
Aug 13, 2012
Messages
72
By only passing the Control, the code can be reduced a bit.
The Control is unique so we don’t need to pass the Form to the HandleFocus Function.

Each Control will need “HighlightOnFocus” in its Tag property.

In a standard module:
...
Chris.
Hi Chris, thanks for your suggestion, the code you posted is less complex indeed, but it needs to set the TAG property for each control and this can be boring with a form having many textboxes, listboxes or other.
Anyway, for simple forms it is a good idea.
Thanks.
Bye.
 

ChrisO

Registered User.
Local time
Tomorrow, 08:18
Joined
Apr 30, 2003
Messages
3,202
>>Hi Chris, thanks for your suggestion, the code you posted is less complex indeed, but it needs to set the TAG property for each control and this can be boring with a form having many textboxes, listboxes or other.<<

No, that is incorrect. The code does not need to set the Tag property at all. The designer of the Form needs to select the required Controls in Design view and add “HighlightOnFocus” to the Tag property. That can be done by holding down the Shift key and selecting the Controls. Then the word “HighlightOnFocus” can be entered into the Tag property.

I’m not just being pedantic here; but your specification in post #1 asked for many controls not for all controls. Using the Tag property allows for some Controls not to be highlighted and hence that method is more flexible.

Chris.
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 23:18
Joined
Sep 12, 2006
Messages
15,660
chris

thanks for confirming you can set control events inside an mde. I am sure it will work in accde also. I just thought you would know the answer without me testing it.

I now realise my original code was slightly wrong, which was why i was having trouble with check boxes, and the fact that your code worked put me on the right track to sort out my problems, and now my check boxes ARE working.

so out of interest, I find a pleasant effect for me is with these settings

- borderstyle 1 for bothactive and non-active (solid)
- borderwidth 2 for active, 0 (hairline) for non-active
- bordercolor whatever for active, 0 (black) for non-active
- note that it must be black to retain the windows theme
- specialeffect 4 (shadowed) for active, 0 (flat) for non-active controls
- shadowed gives a colouring of the dropshadow, for checkboxes. again note the non-active setting must be flat to retain the windows theme

 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 23:18
Joined
Sep 12, 2006
Messages
15,660
My final version

Indebted to ChrisO and BobL for their broadly similar ideas about populating event handlers at run time. It made me look at my code carefully, and I realised I had miscoded my OnExit event handler, which affected the way the checkbox was handled. :banghead:
As a result my code is now a lot simpler. :D

anyway - as far as I am concerned the effect I like best, is for controls to have these settings when highlighted

- specialeffect = 4 (shadowed)
- borderwidth = 2
- borderstyle = 1 (solid)
- bordercolor = whatever you like

the shadowed setting gives a coloured highlight effect to a checkbox which is otherwise missing. Note that these settings cause controls to temporarily lose the windows theme setting.

- rather than having standard settings for the non-highlighted version, i store the original values of these properties in the control's tag, and then reset them to the original on exiting - which retains the windows theme, if available.


open frmDemo to start.

This offers the ability to
- select colour for the highlight
- select whether to highlight attached labels of controls
- adjust dropdown shadow width



View attachment hilite_demo.zip
 

boblarson

Smeghead
Local time
Today, 15:18
Joined
Jan 12, 2001
Messages
32,059
My final version

Indebted to ChrisO and BobL for their broadly similar ideas about populating event handlers at run time.
They should be similar as it was ChrisO I learned this from. And apparently I need to do some revision as I didn't have it quite there to begin with. :D
 

ChrisO

Registered User.
Local time
Tomorrow, 08:18
Joined
Apr 30, 2003
Messages
3,202
Well, Bob, it is not obvious…

Pass ctl.Name and receive as String gives a non-unique Control Name. (We also need the Form Name)
Pass ctl.Name and receive as Control gives a unique Pointer to the Control.

Since the Control Pointer is unique we do not need the Form Name as String.
Since we do not need the Form Name as String then it also works in Sub-Forms.
Remember that Sub-Form Names are not in the Forms collection.

So using the Pointer to the Control not only produces smaller code but also makes it more flexible.

Chris.
 

oxicottin

Learning by pecking away....
Local time
Today, 18:18
Joined
Jun 26, 2007
Messages
856
Chris I stumbled across this VBA you posted and need the same thing except I wanted to know how can I highlight or change the color of the controls label when its control has focus and I wanted to use in a continuous form but when I click on a control all the controls highlight, how can I just highlight the control being clicked on?

Thanks,
 

isladogs

MVP / VIP
Local time
Today, 23:18
Joined
Jan 14, 2017
Messages
18,246
As Chris is no longer with us, have a look at this example which I did for another user a few months ago.
Its for buttons but you may be able to adapt to your needs.
BUT one problem - labels can't receive focus.
You will need to use textboxes or buttons with a transparent background



However in a continuous form, you have multiple copies of the same controls, so anything done to one will happen to all
 

Attachments

  • ButtonGotFocusDEMO.zip
    19.5 KB · Views: 223
  • Capture.PNG
    Capture.PNG
    10 KB · Views: 1,269
Last edited:

Users who are viewing this thread

Top Bottom