Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VFP Program Inactivity Timeout 2

Status
Not open for further replies.

Talbess

Programmer
Apr 29, 2006
17
AU
Hi, I have a problem that I think might be insurmountable, but I thought I'd throw it in to see if any of the experts in this forum can give me some ideas.

I have a program (in vfp6 sp5) that is used by many concurrent users (on a WAN using Terminal Server/Citrix) and some have a habit of walking away and leaving the program running, sometimes for days at a time. I want to shut down each user session after a period of inactivity and I have read the other posts on shutting down vfp programs automatically but I have the following problems:

My application has over 100 forms and the user might walk away with any form having the focus. Setting a timer on every screen would be really difficult - so I'm looking for a timer that is not form-based.

If I find the timer I want, I need to reset the timer on mouse movement or keystrokes. The mouse is not too hard using on key label mouse command, but the keypress has me stumped as there is no on key label (any) or anything that emulates the keypress form event.

So what I am asking is:
1. Is it possible to run a Global Timer that is not dependent on a particular form having the focus
2. If 1. is possible is it possible to capture keypress events in a global way that is also independent of which form has the focus.

Thanks very much for your patience with this very long post.
 
1. Yes. Create a timer class. And in the main programm, instantiate it. Or another option would be to add it to the _SCREEN rather than adding it to all your forms. You would only need to add it once in your startup program.




Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
ReFox XI (www.mcrgsoftware.com)
 
Thanks Mike - I tried adding the timer class to _screen and it seems to do exactly what I want. I only need to shut down after about 2 hours of inactivity so I'm just using on key label mouse to reset the timer - it would be pretty unusual for the mouse to not be clicked for two hours if a user is actually inputting data.
 

Talbess,

it would be pretty unusual for the mouse to not be clicked for two hours if a user is actually inputting data.

You know your users better than I do, but personally I wouldn't make that assumption. There are still many users in the world who do everything from the keyboard.

Still, if your strategy works, that's fine.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Mike,

There are still many users in the world who do everything from the keyboard.
I agree with your comments, it just that I couldn't think of a way to trap activity that didn't interfere with the application. It turns out that using on key label mouse affected all of the _locatebutton foundation classes which I use a lot. With on key label mouse loaded, when I type something in the combobox and click the find button, the contents of the combobox clears. Turn off on key label mouse and it works fine.

I don't want to make any extensive changes to the program to get this inactivity timer working and was wondering if you have any other suggestions on clean ways to determine user activity.
 
Talbess,

I can only say that I have often thought about this problem, but have never come up with a totally satisfactory solution. Even if you trapped every keypress event of every form (which is not all that difficult), you still wouldn't catch people using the keyboard to open a menu, for example.

Also, ON KEY LABEL MOUSE is good for trapping mouse clicks, but not for mouse movements. Then again, does simply moving the mouse count as "program activity"?

Another point: How do you handle the situation where the user has minimised your app, and is working in something else? Do you want to automatically close your app in those circumstances as well?

I don't know the answers to these questions. I'm merely making the point that it's a lot more difficult than it might seem at first.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Thanks again for your time Mike, this is one of those things that started off simple but just gets harder.

Where I am at now is I am using the refresh event of a navigation bar that sits at the bottom of every form to reset the timer. The navigation bar has the usual navigation buttons plus add, delete, browse, locate. The timer only fires a shutdown after two hours of inactivity between 6pm and 5am. The idea here is that we don't want it shutting down in "normal hours" but if the user isn't changing screens or navigation through records, or adding. delet(e)ing or browsing (all of which generate navigation bar refreshes in my app) then the app will be shut down. minimised or not.

I'm running a test with a large site that has a problem with people disconnecting Terminal Server sessions and leaving the app running unattended for days on end - it upsets foxpro when they reboot the server.
 

The timer only fires a shutdown after two hours of inactivity between 6pm and 5am.

That's good, because it will avoid unwanted shutdowns if people leave the app running while they go to lunch or to a meeting.

It will be interesting to hear the results of your tests.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Hi Talbess,

it's a good idea to limit it to the evening and night. I'd like to add another simple On Key Label suggestion and letting the user him/herself participate in the process.

For example in main.prg add a function resetTimer()
Code:
On Key Label Tab ResetTimer("Keyboard '{TAB}' Plain") 

*....

Function ResetTime()
   Lparameters tcFinalCommand

   If Type("_screen.InactivityTimer")="O"
     _screen.InactivityTimer.Reset()
   Endif

   If !Empty(tcFinalCommand) 
      &tcFinalCommand
   Endif
Endfunc

Tabbbing from control to control is rather often used, so this alone might help. You can call the ResetTimer() Function additionally from any other place, like Form.Mousemove() or Form.Keypress with Form.KeyPreview set .T. etc., if applicable. If needed, you can make use of the tcCommand parameter like in this example, if you pass nothing, nothing is executed after the Timer.Reset().

Additionally to that I'd make use of a messagebox displaying a message like "Due to undetected activity this application will quit in ... minutes. Is this okay for you? If you don't want this please click 'No'".

Since VFP7 the messagebox has a timeout parameter you can make use of. Set the timeout high, several more or less minutes don't matter. If the user is still present and your activity detection failed now the user can actively proof he/she is still present. If not, after the timeout the default button (which should be 'Yes') will be returned and the application can quit. Perhaps think of a more friendly message. If you reset the timer in enough places of your application, perhaps no user will ever see this messagebox, if someone really ever experiences it, you may ask how he/she accomplished it despite of just sitting there watching it.

Bye, Olaf.
 
Hi jimstarr,

you are suggesting
Code:
*...
* instanciate Timer _screen.InactivityTimer
Bindevent(_screen,"Keypress",_screen.InactivityTimer,"Reset")

_screen.Keypreview = .T.

I'm not sure if this will fire if a form has the focus, every time, especially but not limited to forms not running "in screen". I think the keypreview mechanism stops at the first form level and _screen will not be informed of each keystroke.

Bye, Olaf.

 
Check out my article "Take advantage of idle cycles" in the December, 2003 FoxPro Advisor. Although my goal was something else, I did look at how you catch all user activity.

Tamar
 
Olaf, Jim, Tamar thanks all for your help.

I'll pick up Olaf's suggestion re using the Tab key to reset the timer - Tab is used a lot and this will provide more security against missed activity. I'm using VFP6 SP5 so messagebox() does not have a timeout.

I had read some other posts re using bindevent() to instantiate _screen.keypress but there were also a few dire warnings. In any case bindevent() is not available in vfp6.

I'm off to dig into the FoxPro Advisor archives to have a look at Tamar's article - thanks.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top