Results 1 to 10 of 10

Thread: How can I catch the form's GotFocus (or LostFocus) event???

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Sep 2000
    Location
    HUNGARY, Pécs
    Posts
    17

    Angry

    In my sourcecode there is LostFocus (and GotFucus) event function but it does'nt called!
    How can I catch that the window become active???

    Sorry about my sux english...

  2. #2
    Frenzied Member Buzby's Avatar
    Join Date
    Jan 1999
    Location
    UK
    Posts
    1,670
    Try putting the code in the Activate and Deactivate events instead - this can work better.

    'Buzby'
    Visual Basic Developer
    "I'm moving to Theory. Everything works there."

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Sep 2000
    Location
    HUNGARY, Pécs
    Posts
    17

    Unhappy I tried it...

    It works not...

  4. #4
    Fanatic Member
    Join Date
    Apr 2000
    Location
    Whats a location?
    Posts
    516
    It's quite complicated. It's called subclassing:

    Code:
    'In a BAS Module
    Option Explicit
    
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal ndx As Long, ByVal newValue As Long) As Long
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    Const GWL_WNDPROC = -4
    
    Public Const WM_ACTIVATEAPP = &H1C
    
    Dim saveHWnd As Long        ' The handle of the subclassed window.
    Dim oldProcAddr As Long     ' The address of the original window procedure
    
    Sub StartSubclassing(ByVal hWnd As Long)
        saveHWnd = hWnd
        oldProcAddr = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WndProc)
    End Sub
    
    Sub StopSubclassing()
        SetWindowLong saveHWnd, GWL_WNDPROC, oldProcAddr
    End Sub
    
    Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, _
        ByVal wParam As Long, ByVal lParam As Long) As Long
        WndProc = CallWindowProc(oldProcAddr, hWnd, uMsg, wParam, lParam)
        
        Select Case uMsg
            Case WM_ACTIVATEAPP
                If wParam Then
                    'Put GotFocus stuff here
                Else
                    'Put LostFocus stuff here
                End If
        End Select
    End Function
    
    'In the form:
    
    Private Sub Form_Load()
    StartSubclassing(Me.hWnd)
    End Sub
    
    Private Sub Form_Unload()
    StartSubclassing(Me.hWnd)
    End Sub
    You have to be very careful when subclassing:

    Never use the End statement.
    Always end the program by pressing the X button (not the stop button)
    Never add breakpoints

    It will crash if there is even the tiniest error, so put 'Save before load' or whatever it says in the project's properties.


    I hope this helps,

    Me
    Courgettes.

  5. #5

    Thread Starter
    Junior Member
    Join Date
    Sep 2000
    Location
    HUNGARY, Pécs
    Posts
    17

    I know this solution...

    There is'nt a simple way???
    I can't belive it!
    Is the VB so primitive?

  6. #6
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649
    The Activate and Deactivate events a fired when the form is created and destroyed.
    The only way you can achieve your goal is by subclassing the form.
    Add the following code to a BAS module:
    Code:
    Private Declare Function SetWindowLong _
     Lib "user32" Alias "SetWindowLongA" ( _
     ByVal hwnd As Long, _
     ByVal nIndex As Long, _
     ByVal dwNewLong As Long) As Long
    
    Private Declare Function CallWindowProc _
     Lib "user32" Alias "CallWindowProcA" ( _
     ByVal lpPrevWndFunc As Long, _
     ByVal hwnd As Long, _
     ByVal Msg As Long, _
     ByVal wParam As Long, _
     ByVal lParam As Long) As Long
    
    Private Const GWL_WNDPROC = (-4)
    Private Const WM_ACTIVATEAPP = &H1C
    Private Const WM_DESTROY = &H2
    
    Public Enum eActivateApp
        NoChange = 0
        Activated
        Deactivated
    End Enum
    
    Public eActivated As eActivateApp
    Private lngHwnd As Long
    Private lngPrevWndProc As Long
    
    Public Sub HookForm(frm As Form)
        lngHwnd = frm.hwnd
        lngPrevWndProc = SetWindowLong(lngHwnd, GWL_WNDPROC, AddressOf WinProc)
    End Sub
    
    Public Sub UnhookForm()
        SetWindowLong lngHwnd, GWL_WNDPROC, lngPrevWndProc
    End Sub
    
    Public Function WinProc( _
     ByVal hw As Long, _
     ByVal uMsg As Long, _
     ByVal wParam As Long, _
     ByVal lParam As Long) As Long
        Select Case uMsg
            Case WM_ACTIVATEAPP
                If wParam = False Then
                    eActivated = Deactivated
                Else
                    eActivated = Activated
                End If
            Case WM_DESTROY
                'the application has been closed
                UnhookForm
        End Select
        WinProc = CallWindowProc(lngPrevWndProc, hw, uMsg, wParam, lParam)
    End Function
    Now in your form add a Timer and set its Interval to 100 and add the following code to the Form module.
    Code:
    Private Sub Form_Load()
        HookForm Me
    End Sub
    
    Private Sub Timer1_Timer()
        Select Case eActivated
            Case Activated
                Debug.Print "GotFocus"
                eActivated = NoChange
            Case Deactivated
                Debug.Print "LostFocus"
                eActivated = NoChange
        End Select
    End Sub
    The Timer is checking the Public variable eActivated if it is set to Activated your form has got the focus.
    But if it's set to Deactivated your form has lost the focus.
    After you have checked these values, and done whatever you want to do, always set the eActivated to NoChange.

    Good luck!

  7. #7
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649
    Sorry V(ery) didn't see your post there.

  8. #8

    Thread Starter
    Junior Member
    Join Date
    Sep 2000
    Location
    HUNGARY, Pécs
    Posts
    17

    Smile Thank You guys!

    THX!!!

  9. #9
    Fanatic Member
    Join Date
    Apr 2000
    Location
    Whats a location?
    Posts
    516
    Originally posted by Joacim Andersson
    Sorry V(ery) didn't see your post there.
    Apologies accepted
    Courgettes.

  10. #10
    Frenzied Member Buzby's Avatar
    Join Date
    Jan 1999
    Location
    UK
    Posts
    1,670
    The Activate and Deactivate events a fired when the form is created and destroyed.
    I don't agree - here is an excerpt from the MS Help file;

    ===============
    Activate, Deactivate Events

    Activate — occurs when an object becomes the active window.

    Deactivate — occurs when an object is no longer the active window.
    Syntax

    Private Sub object_Activate( )

    Private Sub object_Deactivate( )

    The object placeholder represents an object expression that evaluates to an object in the Applies To list.

    Remarks

    An object can become active by user action, such as clicking it, or by using the Show or SetFocus methods in code.

    The Activate event can occur only when an object is visible. For example, a form loaded with the Load statement isn't visible unless you use the Show method or set the form's Visible property to True.

    The Activate and Deactivate events occur only when moving the focus within an application. Moving the focus to or from an object in another application doesn't trigger either event. The Deactivate event doesn't occur when unloading an object.

    The Activate event occurs before the GotFocus event; the LostFocus event occurs before the Deactivate event.

    These events occur for MDI child forms only when the focus changes from one child form to another. In an MDIForm object with two child forms, for example, the child forms receive these events when the focus moves between them. However, when the focus changes between a child form and a non-MDI child form, the parent MDIForm receives the Activate and Deactivate events.

    If an .exe file built by Visual Basic displays a dialog box created by a .dll file also built in Visual Basic, the .exe file's form will get the Deactivate and LostFocus events. This may be unexpected, because you should not get the Deactivate event:

    If the object is an out-of-process component.


    If the object isn't written in Visual Basic.


    In the development environment when calling a DLL built in Visual Basic.

    ==============

    I have written a program before that changes toolbar icons depending on the currently focused MDI child form (like most MS programs do) - and I achieved this using the Gotfocus, Lostfocus, Activate and Deactivate events.

    'Buzby'
    Visual Basic Developer
    "I'm moving to Theory. Everything works there."

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width