How to Trap VB Form Lost Focus with GetActiveWindow API

ID Number: Q69792

1.00

WINDOWS

Summary:

The LostFocus event in Microsoft Visual Basic is useful when

transferring control within an application. However, no global routine

exists to check for the entire form losing the focus. One method to

use to check whether your Visual Basic application has lost the focus

is by periodically checking the Windows API function GetActiveWindow

in a Visual Basic timer event, as explained below.

This information applies to Microsoft Visual Basic programming

system version 1.0 for Windows.

More Information:

The only way that Visual Basic provides a check for loss of focus on a

form or control is by triggering the LostFocus event. A form does

support a LostFocus event; however, a form will only get focus if

there are no controls on that form. Focus goes to the controls on a

form, and when you click any other visible form, the control's

LostFocus procedure will be called. A control's LostFocus procedure

will also be called when another control on the form is activated. To

perform a routine that occurs only when the form loses focus requires

careful management of what generated a LostFocus event on each control

(such as setting a flag if another control's Click event was called).

For a simpler method to check if a whole form has lost the focus, you

can call the Windows API function GetActiveWindow, located in USER.EXE

(a DLL provided with Windows 3.0). The GetActiveWindow API call

returns the window handle of the currently active window, which is the

new window that you last clicked anywhere in Microsoft Windows. In a

timer event procedure for the form, call GetActiveWindow and compare

the handle of the currently active Window with the handle of the form

window (Form1.hWND). If the handle differs, you know the form has lost

the focus. The following program example demonstrates this technique:

Program Example

---------------

This single-form example will print "Lost Focus" on the form when you

click a different window (such as when you click another program

running in Windows).

In Visual Basic, draw one timer control (Timer1) and one command

button (Command1) on a single form (Form1).

From the VB.EXE Code menu, choose View Code, and enter the following

code for Form1, using (general) from the Object box, and

(declarations) from the Procedure box:

Declare Function GetActiveWindow Lib "User" () As Integer

Dim FOCUS As Integer

Const TRUE = -1

Const FALSE = 0

From the Object box, choose Timer1, and from the Procedure box, choose

Timer, and then put the following code in the Timer1_Timer procedure:

Sub Timer1_Timer ()

If FOCUS = TRUE Then

' Compare the handle of the currently active Window with the handle

' of the Form1 window:

If GetActiveWindow() <> Form1.hWND Then

'Do form's lost-focus routines here.

Print "Lost Focus"

FOCUS = FALSE

End If

End If

End Sub

You must set FOCUS=TRUE in the Click event procedure of every control

on the form, as follows:

From the Object box, choose Command1, and from the Procedure box, choose

Click, then put the following code in the Command1_Click procedure:

Sub Command1_Click ()

FOCUS = TRUE

End Sub

Double-click on Form1 (at design time) and enter the following code

for the Form_Click procedure:

Sub Form_Click ()

FOCUS = TRUE

Timer1.Interval = 10

End Sub

You can now run the program.

Reference(s):

"Programming Windows: the Microsoft Guide to Writing Applications for

Windows 3," Charles Petzold. Microsoft Press, 1990.

"Microsoft Windows Software Development Kit: Reference Volume 1,"

version 3.0.

WINSDK.HLP file shipped with Microsoft Windows 3.0 Software

Development Kit.

Additional reference words: 1.00 3.00