Lost Focus event does not fire when clicking external window

willjones

Registered User.
Local time
Yesterday, 18:10
Joined
Mar 24, 2007
Messages
13
It seems that when a control has focus and then I click on a window outside of Access, such as a Windows Explorer folder window or something... that the LostFocus event does not fire.

I have a listView with images on it. I modified the images to look differently when selected (Highlighted) by adding a blue background to them to match the rest of the blue color shown on that row. Then on the lost focus event of the listview I remove the blue highlighting. For the most part this works great, but if I click on an external window it just switches focus to the external window removes the other highlighted portions, but does not call my lost focus event! So the images are left on the list view with the blue background, even though the row isn't being shown as highlighted anymore.

Anyone know how I can execute code when an event occurs where the user clicks an external window?

Thanks,
Will
 
I assume you're talking about the form losing focus! From Access 2000 Help:

A form can get the focus only if all visible controls on a form are disabled, or there are no controls on the form.
And hence if the form doesn't have focus, it can't lose focus. I have no idea, sorry.
 
I believe the form will get a Deactivate event.
 
then I click on a window outside of Access...where the user clicks an external window?

From Help:

The Activate and Deactivate events occur only when you move the focus within an application. Moving the focus to or from an object in another application doesn't trigger either event.
 
I just stumbled across it the other day researching something for somebody!

How are things in the Rockies? Still got snow up there? :D

Linq
 
Snow on the peaks, you bet, but not at my altitude. We did get about an inch a couple of week ago though. Lots of spring growth around here right now. The oak brush finally woke up and started sprouting. Moisture almost every day. Life is good.
 
Last edited:
Found a solution

OK, I finally found some solutions to this problem on my own...

I thought I'd post them here for the benefit of others.

I located this post that gave me some useful information/ideas:
http://www.programmersheaven.com/mb/VBasic/14950/14950/readmessage.aspx

(and this post http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1683391&SiteID=1 )

Checking for the WM_ACTIVATEAPP message and subclassing your form could probably be used somehow for a possibly cleaner solution that could actually respond to an event, but after seeing how the debugger gets easily broken without the use of an external dll (such as DbgWProc.dll) when subclassing I decided to try and avoid subclassing if at all possible. (You might also be able to make an external dll that does the subclassing and avoid the debugger problems, but I'm trying to minimize external dependencies for my MDB.)

-------------
My solution:

I have a class module that has a method called LostFocusChecker which has an infinite loop with DoEvents. It serves as a sort of daemon which constantly checks whether or not I've lost focus from the current window with the use of the GetForegroundWindow API. LostFocusChecker is the last thing called from my Initialize method and the Initialize method must be the last thing called from Form_Load in the parent form. The class has a private member variable called unload which stays false throughout the life of the form. When the form unloads it must call my class's unload method which sets the boolean value to true. The infinite loop checks for the unload = true state and ends when this happens. (So technically it's not really infinite.) This works because the DoEvents call allows all other events to continue occurring like normal while my LostFocusChecker is polling for whether the current window has lost focus or not using the GetForegroundWindow API [ Private Declare Function GetForegroundWindow Lib "user32" () As Long ]. (This is the closest thing to threading in VBA I could figure out how to do.) I got this idea after looking at Kevin Wilson's autonomous Timer class that doesn't need the use of subclassing. (http://www.thevbzone.com/cTimer_NoSC.cls)
 
Another Way

OK, I just realized there is another way to accomplish what I was doing without the use of DoEvents. If you replace the tight loop that calls the LostFocusChecker over and over again and has DoEvents in there with a Form_Timer event that periodically calls the LostFocusChecker then the use of DoEvents is no longer necessary. In my Form_Load after initializing my checkbox listview class instance I just set Me.TimerInterval=1. Then in Form_Timer I just call myCheckboxListViewClassInstance.LostFocusChecker.
 

Users who are viewing this thread

Back
Top Bottom