|
-
Sep 1st, 2000, 05:12 AM
#1
Thread Starter
Junior Member
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...
-
Sep 1st, 2000, 05:27 AM
#2
Frenzied Member
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."
-
Sep 1st, 2000, 05:31 AM
#3
Thread Starter
Junior Member
I tried it...
It works not...
-
Sep 1st, 2000, 05:32 AM
#4
Fanatic Member
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
-
Sep 1st, 2000, 05:39 AM
#5
Thread Starter
Junior Member
I know this solution...
There is'nt a simple way???
I can't belive it!
Is the VB so primitive?
-
Sep 1st, 2000, 05:39 AM
#6
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!
-
Sep 1st, 2000, 05:43 AM
#7
Sorry V(ery) didn't see your post there.
-
Sep 1st, 2000, 05:46 AM
#8
Thread Starter
Junior Member
Thank You guys!
-
Sep 1st, 2000, 05:51 AM
#9
Fanatic Member
Originally posted by Joacim Andersson
Sorry V(ery) didn't see your post there.
Apologies accepted
-
Sep 1st, 2000, 06:01 AM
#10
Frenzied Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|