Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Changing backcolor for ALL controls on a form 3

Status
Not open for further replies.

Kobayashi

Technical User
Oct 11, 2001
69
US
I would like to know if anybody has a general function which can be used, perhaps in the form's OnLoad or OnOpen event, to change the backcolor of all controls on a form depending which control currently has the focus, without having to add an event to each individual controls OnGotFocus event?
I thought I had found the answer a couple of times from this site but not quite.

I guess the function will contain the Dim ctr As Control and For Each ctr statements, but after that I'm lost I'm afraid.

Many thanks in advance.

Adrian
 
Adrian,
The best way to do this *is* to put the thing in each controls event, heres the EASY way how:
Create 2 function, one for Got and one for Lost focus, ie

Function SetBlue() <---Then do a similar one of the contrasting colors for LostFocus
'This for GotFocus
On Error Resume Next 'just in case--better to have color not change than an error msg
screen.activecontrol.backcolor = vbBlue
screen.activecontrol.Forecolor = vbWhite '(Not sure of the color constant's but you get the picture)
End function

Now, the easy part--I do alot of 'Code Generation' in Access for just such occasions

Sub Work_Smarter_Not_Harder()
'for development only, sets event proc on mass group of controls
Dim db As Database, F As Form, i As Integer, c As Control
docmd.openForm &quot;frmTickets&quot;,acDesign
Set F = Forms!frmTickets
For Each c In F
If TypeOf c Is TextBox Or TypeOf c Is ComboBox Then
If c.onGotFocus <> &quot;&quot; then
debug.print &quot;Sorry, you'll have to manualy add to existing fcn for &quot; & c.name
Else
c.OnGotFocus = &quot;=setltblue()&quot; 'your ready-made color change function
End If
If c.onLostFocus <> &quot;&quot; then
debug.print &quot;Sorry, you'll have to manualy add to existing fcn for &quot; & c.name
Else
c.OnLostFocus = &quot;=setwhite()&quot;
End If
End If
Next c
End Sub
--Jim
 
Try this:

Sub ChangeBackColor()
On Error Resume Next
Dim Ctl As Control
For Each Ctl In Me.Controls
ctl.BackColor = Screen.ActiveControl.BackColor
Next

End Sub

Uncle Jack
 
Jim,

Many thanks for your response. I am continually amazed how helpful people are on this site!
A couple of questions though: do I put the GotFocus function and the Lost focus functions in every GotFocus/LostFocus control events on my form?

Also, do I put the Sub Work_Smarter_Not_Harder() procedure in the Forms module? As I have done this but the backcolors haven't changed?

All the best

Adrian
 
Uncle Jack,

Does this code go in the Forms module? And how do I specify what the backcolor should be?

Thanks

Adrian
 
Your question suggested OnLoad or OnOpen - but that's up to you. The color will change to the color of the control that has the focus when it's run. Wasn't that what you wanted?

Uncle Jack
 
Uncle Jack,

OnLoad or OnOpen is exactly what I wanted.
However, I want to be able to specify the backcolor of the control that currently has the focus. Something like:
Me.Control.backcolor = vbblue
But for each control in the form that currently has the focus.
How can I fit this in with the code you supplied?

Adrian
 
Adrian,
It doesn't matter where the Work_Smarter_Not_Harder goes, that's just a 'code generator' that you use once. You may want to keep it though and use it to make other bulk changes to forms, etc.

You would put the SetBlue() (in this example--the name of the function and the colors it change are, of course, up to you) into the GotFocus and another one into the LostFocus events, doing this via the Work_smart... function. You put it into any control that can recieve focus. Now, the control with the focus is 'highlighted'. I assumed this is what you were going for?

Another note: the Screen.ActiveControl property used in the functions is not always foolproof, ultra-fast keying has cause a box to stay blue (or whatever color) for me from time to time. An option is to go into the Work_Smater... code, and hardcode into the event procedure the following:
c.OnGotFocus = &quot;=setltblue(Forms!ThisFormsName!&quot; & c.name &quot;)&quot;
Note that you must put the argument as a parm in the setblue: SetBlue(C as control)
and change the code in SetBlue to c.backcolor = vbBlue
(Also note you can't use &quot;Me&quot; in the event procedure line--it's not valid in that context.)

Am I right in assuming you wanted this fired on the control with the focus?
--Jim
PS--you can put a breakpoint in SetBlue() and make sure it's being fired, and maybe remove the On error resume next to see if an error is occurring--but when that's found & fixed, put the resume next back in--as a rule--better to have it do nothing than give an error.
 
Jim,

I really didn't want to have to physically enter code into every GotFocus event and LostFocus event of every control!
So the procedure you have provided is 100% what I was looking for, in that it does this for you.
I also do wanted the option to have a general procedure that I can use for any form, and again it seems that this can be used for that as well!
I'm going to test it now and will let you know how I get on.

Again, many thanks.

Adrian
 
Jim,

Works like a dream - with one minor problem (there would be wouldn't there?!).
If one of the text boxes has any text in it - a default date() value for instance, then although the text changes to the color I choose in the sub and the backcolor of the text box changes to the color I choose there seems to be another kind of backcolor, which is white, behind the text, which obscures most of the backcolor I've chosen?

Any ideas?

Adrian
 
Adrian,
I'm not sure about that, could it be the standard 'selected' behaviour, ie. when you drag the mouse across a field of text to highlight, it clashes with the new user-defined highlighting?
--Jim
 
Jim,

Sorry, it's me being a bit thick! It is the Forecolor that I've selected that is showing!
It seems that if you have a backcolor of blue and a forecolor of white for example, then the actual text colour will be that of the backcolor behind -in this case blue.
Something else I've learned!

Many thanks once again! I've been looking for a procedure that you have provided for some weeks now, and I've got the procedure working perfectly!
I've also learned quite a bit.

All the best

Adrian
 
Here you go Adrian,
This is a little different and gives you two options and two different results:

Private Sub ResetColor()'drop in your form's module anywhere.
On Error Resume Next
Dim ctl As Control
Set ctl = Me.ActiveControl
For Each ctl In Me.Controls
If ctl.ControlType = acTextBox Then ctl.BackColor = vbBlue 'your choice
Next
Me.ActiveControl.BackColor = vbRed 'your choice
End Sub

'add this simple line to your forms detail (and any other sections) as you wish. It's only one simple line. Notice that this will only make things work if the mouse pointer is over these sections: if your pointer is off on the menu or even on a text box, nothing happens (kinda cool in its own way...)

Private Sub Detail_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
ResetColor
End Sub

if you want to guarantee to make things work 110% add this simple line to each gotfocus event. No need to handle it in both got and lost, as lost usually means got somewhere else!

Private Sub TxtBoxOne_GotFocus()
ResetColor
End Sub

I see mouse move events are not being used very much in Access, and if you want to really give your forms some of the 'XP' or 'web-ish' look, start fooling with these. You might consider to change the color and the special effect:
On Error Resume Next
Dim ctl As Control
Set ctl = Me.ActiveControl
For Each ctl In Me.Controls
If ctl.ControlType = acTextBox Then
ctl.BackColor = vbBlue
ctl.SpecialEffect = 2
End If
Next
Me.ActiveControl.BackColor = vbRed
Me.ActiveControl.SpecialEffect = 1

and so on...
Your screen may get a little shakey depending on your computer, but it's fun regardless... Gord
ghubbell@total.net
 
Gord, that's great.

I did put it on the Got Focus for each textbox as well to activate the function when I was clicking on a textbox.

One question: When I pasted the code into my module, I thought, &quot;Gee, Gord forgot the &quot;End If&quot; statement.&quot;
Code:
      For Each ctl In Me.Controls
             If ctl.ControlType = acTextBox Then ctl.BackColor = vbBlue  'your choice
It compiled with no problem. It ran with no problem.

Is this because the entire If...then is on the same line?

Learn something new every day (and then take a nap)!

Thanks.

John

Use what you have,
Learn what you can,
Create what you need.
 
Thanks John,
Yessir, there's some really technical jargon about doing this but if you have a single then condition of an 'If' it's legally a one liner. I always try to keep the code short and sweet as I like to nap too! Gord
ghubbell@total.net
 
Gord,

Many thanks for getting back to me! It's a little late right now, but I can't wait to try the code tomorrow!
I'll let you know how I get on.

Thanks Again.

Adrian
 
Gord/Jim,

Thanks. The procedures work really well!
What about this though:
What if I have a form where the text boxes etc. are NOT all formatted with the same backcolors and forecolors? Using the procedures above, after the text boxes have Got and then Lost the focus they will be changed to the format of the backcolor and forecolor that I have specified in the LostFocus event - all the same.
Is it therefore possible to keep the GotFocus part of the procedure; changing the backcolor when the textbox has focus, but then reverting to the default formatting values of the textboxes when the focus has been Lost?

Adrian
 
Try adding this:

For Each ctl In Me.Controls
'If this is a special color, then make no change
Select Case (ctl.BackColor)
Case Is = 10092530 '<--- Your colours go in here
ctl.BackColor = 10092530
Case Is = 10053222
ctl.BackColor = 10053222
Case Is = 8404992
ctl.BackColor = 8404992
Case Else
'Otherwise set the backcolor as required
If ctl.Name = strLabelName Then
ctl.BackColor = 10092543
Else
'or set it back to standard
ctl.BackColor = 16764057
End If
End Select
Next ctl

It's an adaption of some code that Gord gave me earlier this year, so it should work reasonably well for you.

Welcome back Gord!

Lightning
 
Lightning! Hey there bud! Are you warming up, ready for some more bad Canadian puns? Let me think up a quick one for old times sake...Would you believe I've been 'grounded' for a few months? Ya, they're not getting any better!
Thanks and good to hear from you! Gord
ghubbell@total.net
 
Adrian,
It's a good practice to get in the habit of making things like this 'table-driven'. What that means in this case, is to make a small table, load it (you can load it in a loop similar to the loop that sets the Got/Lost focus events--automate everything if you can!)

The table, we'll call it tblCtrlColor, will have several fields, depending on how involved you want to get.
Key field is CtrlName, which you'd have the name of each control on the form. The other fields might be
CtrlNormalForeColor
CtrlNormalBackColor
CtrlFocusForeColor
CtrlFocusBackColor
Load the appropriate color values.
Now, you can rename the SetBlue and SetWhite so they're not confusing (since Blue and White aren't relavent here anymore)
Name them something like HiLite() and UnHilite().
Then, the code looks like this:

Function HiLite() 'for the GotFocus Event
on error resume next
dim x

x = dlookup(&quot;CtrlFocusForeColor&quot;,&quot;tblCtrlColor&quot;,&quot;CtrlName = '&quot; & Screen.Activecontrol.name & &quot;'&quot;)
Screen.Activecontrol.Forecolor = x

x = dlookup(&quot;CtrlFocusBackColor&quot;,&quot;tblCtrlColor&quot;,&quot;CtrlName = '&quot; & Screen.Activecontrol.name & &quot;'&quot;)
Screen.Activecontrol.Backcolor = x
'(you can use a Control variable to save the multiple calls to Screen.ActiveControl)
End Function

The UnHilite would have the appropriate corresponding changes, you get the picture.

The reason for thinking of things in a 'table driven' way is that you can make changes to the colors (in this case) at will without even shutting down the db--users can be using the live app and you can test color changes without changing a bit of code. And that table is so small, the access to it will be extremely fast--it's not like it will slow down your app at all. Things to speed up the app might be dimming a Form-Scoped variable of Control type, and assigning the Screen.ActiveControl to this var. Form scope will save time since you're not dimming and killing the variable on every single focus event, and since you're referencing the ActiveControl 4 times, assigning to a var. makes sense.

I also recommend passing the control name in the HiLite function call, so when you automate the populating of the Got/Lost focus events, hardcode the controlname, and accept it in the Functions as a string, or send it as the control itself.

I hope this helps,
--Jim
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top