Link to home
Start Free TrialLog in
Avatar of HunterKiller
HunterKillerFlag for Brazil

asked on

Change Label when every control get Focus

I have a label that displays the tool tip of the current control.
Until now, I used, of course, the Got Focus evnt of each control, what means I had lots of repeated code. But now I have a form with more then 40 controls that can get focus, and writing the same code 40 times... Is there any way to do this task easier ?

Thanks in advance..
Avatar of AnswerTheMan
AnswerTheMan

1.
many controls have a TOOLtip property that can be set both at design time and tun time SO you better use it.
2.
for controls of same type - you can use control-arrays where the event code is 1 for all controils in the array. obviously - you'll have to have some select case code inside that event code to check which one of them got the event.
3.
GotFocus event is not the place to display ToolTip . traditionaly, the mouseMove event or rightClick are used.
This should trim down your code a little, and make the programming go a little faster.  I don't think there is any way to avoid putting at least a little code in the gotfocus event, but give this a try:

Add this sub to your project-

Private Sub Show_Tips()

    lblToolTips.Caption = frmMyForm.ActiveControl.ToolTipText

End Sub


Then in the gotfocus event of each control you need to display the tooltip call Show_Tips()
Avatar of HunterKiller

ASKER

Thanks AnswerTheMan, but
1- I use the ToolTip of the control as source for the label (In fact, it is not as labal, but a Status bar);
2- I've tried arrays before...
3- What do you do if the form is operated only with the keyboard ?

jjmartin, I've tried this before. The movement through controls in the form is done by a KeyPress Event on the form. Enter goes to the next control (send a TAB) and ESC goes to the previous (with +TAB). I've tried something here, where I'm changing the focus, with ActiveControl. But I don't know why it's not working... Here is the code:

Private Sub Form_KeyPress(KeyAscii As Integer)
  If KeyAscii = vbKeyReturn Then
    SendKeys "{TAB}"    
  End If
  If KeyAscii = vbKeyEscape Then
    SendKeys "+{TAB}"    
  End If
  frmEstoque.sbrEstoque.Panels(2).Text = Me.ActiveControl.ToolTipText
End Sub
There is still a problem with the Form_KeyPress because the user can use the mouse to change the Focus...
There is nothing wrong with the code:
frmEstoque.sbrEstoque.Panels(2).Text = Me.ActiveControl.ToolTipText.
The problem is, where do you put this code. It won't work in the Keypress or KeyUp/Down events because none of these events will capture the Tab key. (at least in VB5.0 that I'm using).
The only event I could think of putting it under is the timer event on a timer control. The interval could be set low enough to give realtime response, the question is, how badly will it affect your program's overall response.
Outside of this the only other suggestion I have is to put the code frmEstoque.sbrEstoque.Panels(2).Text = Me.ActiveControl.ToolTipText into every control's gotfocus event.
Good Luck.
P.S. if you find a better solution could you please e-mail me at KABBOTT1@SAN.RR.COM I'd really like to know if there's a better way of doing this.
thanks.
ASKER CERTIFIED SOLUTION
Avatar of WatsonR
WatsonR

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sorry... global edit cockup

The bit in the middle of the class should have read...

Private Sub cboControl_GotFocus()
    mpGotFocus cboControl
End Sub

Private Sub txtControl_GotFocus()
    mpGotFocus txtControl
End Sub
Well Chaos, take a look at WatsonR's answer. It is just great ! I knew that it had to exist. Thanks a lot WatsonR, and come get your points !  Man, I love this place !
Thanks !!!!
What is the passed to Value in the Class ??

Sometimes I get errors, when a CommandButton receives False
and other errors

Would you mind to send me a mail about this ?  My address is
lukeagnc@zipmail.com.br

Thanks in advance...
"What is passed to Value ?"

Well... it's an instance of a VB control. If you attempt to examine that instance, it's more than likely that what you'll see is the default property for the control (unless you specify some valie property for that control type). In the case of a command button, that default property is (I think) "Value", which is True or False. (You used, in earlier versions of VB, to have to set a command button to True to simulate a click).

What errors do you see ?
HunterKiller has just pointed out to me that, while this code works fine most of the time, it gets rather upset when control arrays are used.
I've had a quick look to see if I can find a solution to that, but to no avail. Therefore...

Below is an example of how to hook into the windows messages, catch the "GotFocus" and do something with it.

I'll continue and see if I can find a rather less hazardous way to get around the problem.

Warning: What this code does is rather more 'involved' than the previous suggestion. Also, you *MUST* unhook the custom handler upon program exit - press the IDE "Stop" button at your peril.
The "Hookup" and "Unhook" need only be called once per application - not per form.

(Form1)
Private Sub Form_Initialize()
    Hookup
End Sub

Private Sub Form_Terminate()
    Unhook ' this *MUST* be executed
End Sub

Public Sub Control_GotFocus(Control As VB.Control)
    Debug.Print Control.Name & " has focus"
End Sub

(Module1)
Option Explicit

Type CWPSTRUCT
    lParam  As Long
    wParam  As Long
    Message As Long
    hWnd    As Long
End Type

Declare Function SetWindowsHookExA Lib "user32" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hMod As Long, ByVal dwThreadId As Long) As Long
Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Sub memcpy Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cbLength As Long)

Public Const WH_CALLWNDPROC = &H4
Public Const WM_SETFOCUS = &H7

Private mhHook As Long

Public Sub Hookup()
    mhHook = SetWindowsHookExA(WH_CALLWNDPROC, AddressOf CallWndProc, App.hInstance, App.ThreadID)
End Sub

Public Sub Unhook()
    If (mhHook <> 0) Then UnhookWindowsHookEx mhHook
End Sub

Private Function CallWndProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim CWP As CWPSTRUCT
    If (nCode >= 0) Then
        memcpy CWP, ByVal lParam, Len(CWP)
        Select Case CWP.Message
        Case WM_SETFOCUS: mpRaiseEvent CWP.hWnd, CWP.Message
        End Select
    End If
    CallWndProc = CallNextHookEx(mhHook, nCode, wParam, ByVal lParam)
End Function

Private Sub mpRaiseEvent(ByVal hWnd As Long, ByVal Message As Long)
    Dim Form    As VB.Form, _
        Control As VB.Control
   
    For Each Form In Forms
      For Each Control In Form.Controls
        If (Control.hWnd = hWnd) Then
          Call Form.Control_GotFocus(Control)
          Exit Sub
        End If
      Next Control
    Next Form
End Sub