Application Time out

  • Thread starter Thread starter Morten Wennevik
  • Start date Start date
M

Morten Wennevik

You can put a timer that increments a value every now and then, and if the value goes above some limit, ask for a new login.
This isn't very elegant though since you will need to reset the value at every type of user input.

Happy coding!
Morten Wennevik [C# MVP]
 
* "Alok said:
how can i implement an application timeout??
If the app has no messages for a pre-configured time, i want to pop-up a
modal box asking for the password.

I tried the Idle event of the application. But it didn't seem to work.
Any other ideas ??

Add a timer control ('System.Windows.Forms.Timer') to your form, then
define a private variable of type 'Integer' (a counter). In the timer's
'Tick' event handler, increment the variable and check if its value is
bigger than the timeout period.
 
my application is a typical mdi windows app that could have anywhere from
5 - 30 windows open. Programmatically, it would be very difficult to
handle

it would be easy if you declare your own MyForm class that iherits the Form
class and overrides mouse and keyboard events (to reset the counter). then,
let all other form inherit from MyForm and you no longer have to worry about
resetting the timer.

Regards,
Wiktor Zychla
 
But the problem is that mouse move events for the Mdi Form do not occur
!!!!!
Any idea why ???

perhaps you should try to locate the MdiClient control of the MDI window and
add a handler there:

// somewhere inside the mdi window:
foreach (Control c in this.Controls)

{

if ( c is MdiClient )

{

((MdiClient)c).MouseMove += ...

((MdiClient)c).anyotherevent += ...

}

}
 
I made a small component for handling that before, the way I handled it was
to
call Application.AddMessageFilter on the component (in its constructor).
Then in the PreFilterMessage function I checked for the following messages:

WM_MOUSEMOVE (512)
WM_LBUTTONDOWN (513)
WM_RBUTTONDOWN (516)
WM_MBUTTONDOWN (519)
WM_KEYDOWN (256)

The only case I found where that wont trigger is if the user is moving
around in menus only.
I never wound up using it in live code so I never took the time to find how
to handle that.

It worked fairly well in all other cases though
Hope it helps
/Dan

Alok said:
Hi,
Thanx a lot
But the problem in that case is that even a simple mouse move event would
need the counter to be reset.
my application is a typical mdi windows app that could have anywhere from
5 - 30 windows open. Programmatically, it would be very difficult to handle
the mouse and keyboard events.

Can you suggest any other options based on the idle event of the Application
class. if reqd. i can post the code here.

TIA :)
 
Hi,
how can i implement an application timeout??
If the app has no messages for a pre-configured time, i want to pop-up a
modal box asking for the password.

I tried the Idle event of the application. But it didn't seem to work.
Any other ideas ??

TIA :)
 
Hi,
Thanx a lot
But the problem in that case is that even a simple mouse move event would
need the counter to be reset.
my application is a typical mdi windows app that could have anywhere from
5 - 30 windows open. Programmatically, it would be very difficult to handle
the mouse and keyboard events.

Can you suggest any other options based on the idle event of the Application
class. if reqd. i can post the code here.

TIA :)
 
Hi Wiktor,
Thanx for the suggestion.
i tried something like that.
But the problem is that mouse move events for the Mdi Form do not occur
!!!!!
Any idea why ???
 
Hi H.

I had the same issue (In Visual Basic) and contacted Microsoft. I am designing a windows forms application, so if thats your thing, heres the answer.

I shall give you the theory, you will have to write the C++, as I was using VB.

Write a global function called InstantiateHandlers which takes an argument of cntl as control. Then, write a function which calls the function that does what you want after the give period (for this example we will call it DoSomething() ). I will give you the code for the InstantiateHandlers routine in VB. You will have to work out the C++ from that :

Friend AutoHibernateTimerCounter as Integer = 0 'increment this for each parse of the timer
Friend AutoHibernateTimerCounter_MaxValue as integer = 60 'the number of seconds that the timer must increment (without the users interaction) before the DoSomething() function fires
Friend AutoHibernateEnabled as Boolean = True 'if you wish the user to be able to turn on/off wether it checks for user interaction, then .

Friend Sub InstantiateHandlers(ByRef Cntl As Control)

'Purpose: To add the handler to the events of every control
' within the specified form, and also to the form itself,
' which execute whenever an event is fired on them.
' This handler will reset the global counter so that
' the autohibernate function can be realised.

'if the control doesnt have the specific event, then
'continue to the next command
On Error Resume Next

AddHandler Cntl.Click, AddressOf resetsub
AddHandler Cntl.CursorChanged, AddressOf resetsub
AddHandler Cntl.DockChanged, AddressOf resetsub
AddHandler Cntl.DoubleClick, AddressOf resetsub
AddHandler Cntl.DragDrop, AddressOf resetsub_Drageventargs
AddHandler Cntl.DragEnter, AddressOf resetsub_Drageventargs
AddHandler Cntl.DragLeave, AddressOf resetsub
AddHandler Cntl.DragOver, AddressOf resetsub_Drageventargs
AddHandler Cntl.Enter, AddressOf resetsub
AddHandler Cntl.GiveFeedback, AddressOf resetsub_givefeedbackeventargs
AddHandler Cntl.ContextMenuChanged, AddressOf resetsub
AddHandler Cntl.EnabledChanged, AddressOf resetsub
AddHandler Cntl.ImeModeChanged, AddressOf resetsub
AddHandler Cntl.KeyDown, AddressOf resetsub_Keyargs
AddHandler Cntl.KeyPress, AddressOf resetsub_Keypresseventargs
AddHandler Cntl.KeyUp, AddressOf resetsub_Keyargs
AddHandler Cntl.Layout, AddressOf resetsub_layouteventargs
AddHandler Cntl.Leave, AddressOf resetsub
AddHandler Cntl.LocationChanged, AddressOf resetsub
AddHandler Cntl.MouseDown, AddressOf resetsub_mouseeventargs
AddHandler Cntl.MouseEnter, AddressOf resetsub
AddHandler Cntl.MouseHover, AddressOf resetsub
AddHandler Cntl.MouseLeave, AddressOf resetsub
AddHandler Cntl.MouseMove, AddressOf resetsub_mouseeventargs
AddHandler Cntl.MouseUp, AddressOf resetsub_mouseeventargs
AddHandler Cntl.Move, AddressOf resetsub
' AddHandler Cntl.Paint, AddressOf resetsub_Painteventargs
AddHandler Cntl.ParentChanged, AddressOf resetsub
AddHandler Cntl.QueryContinueDrag, AddressOf resetsub_QueryContinueDrageventargs
AddHandler Cntl.Resize, AddressOf resetsub
AddHandler Cntl.RightToLeftChanged, AddressOf resetsub
AddHandler Cntl.SizeChanged, AddressOf resetsub
AddHandler Cntl.StyleChanged, AddressOf resetsub
AddHandler Cntl.SystemColorsChanged, AddressOf resetsub
AddHandler Cntl.TabIndexChanged, AddressOf resetsub
AddHandler Cntl.TabStopChanged, AddressOf resetsub
AddHandler Cntl.TextChanged, AddressOf resetsub
AddHandler Cntl.Validated, AddressOf resetsub
AddHandler Cntl.Validating, AddressOf resetsub_Validatingeventargs
AddHandler Cntl.VisibleChanged, AddressOf resetsub

Dim subcntl As Control
For Each subcntl In Cntl.Controls
Call InstantiateHandlers(subcntl)
Next

End Sub
Friend Sub DisposeHandlers(ByRef Cntl As Control)

'Purpose: If the handlers are instantiated, we need to
' have some code that removes them if the form/control
' is hidden/closed

'if the control doesnt have the specific event, then
'continue to the next command
On Error Resume Next

RemoveHandler Cntl.Click, AddressOf resetsub
RemoveHandler Cntl.CursorChanged, AddressOf resetsub
RemoveHandler Cntl.DockChanged, AddressOf resetsub
RemoveHandler Cntl.DoubleClick, AddressOf resetsub
RemoveHandler Cntl.DragDrop, AddressOf resetsub_Drageventargs
RemoveHandler Cntl.DragEnter, AddressOf resetsub_Drageventargs
RemoveHandler Cntl.DragLeave, AddressOf resetsub
RemoveHandler Cntl.DragOver, AddressOf resetsub_Drageventargs
RemoveHandler Cntl.Enter, AddressOf resetsub
RemoveHandler Cntl.GiveFeedback, AddressOf resetsub_givefeedbackeventargs
RemoveHandler Cntl.ContextMenuChanged, AddressOf resetsub
RemoveHandler Cntl.EnabledChanged, AddressOf resetsub
RemoveHandler Cntl.ImeModeChanged, AddressOf resetsub
RemoveHandler Cntl.KeyDown, AddressOf resetsub_Keyargs
RemoveHandler Cntl.KeyPress, AddressOf resetsub_Keypresseventargs
RemoveHandler Cntl.KeyUp, AddressOf resetsub_Keyargs
RemoveHandler Cntl.Layout, AddressOf resetsub_layouteventargs
RemoveHandler Cntl.Leave, AddressOf resetsub
RemoveHandler Cntl.LocationChanged, AddressOf resetsub
RemoveHandler Cntl.MouseDown, AddressOf resetsub_mouseeventargs
RemoveHandler Cntl.MouseEnter, AddressOf resetsub
RemoveHandler Cntl.MouseHover, AddressOf resetsub
RemoveHandler Cntl.MouseLeave, AddressOf resetsub
RemoveHandler Cntl.MouseMove, AddressOf resetsub_mouseeventargs
RemoveHandler Cntl.MouseUp, AddressOf resetsub_mouseeventargs
RemoveHandler Cntl.Move, AddressOf resetsub
' RemoveHandler Cntl.Paint, AddressOf resetsub_Painteventargs
RemoveHandler Cntl.ParentChanged, AddressOf resetsub
RemoveHandler Cntl.QueryContinueDrag, AddressOf resetsub_QueryContinueDrageventargs
RemoveHandler Cntl.Resize, AddressOf resetsub
RemoveHandler Cntl.RightToLeftChanged, AddressOf resetsub
RemoveHandler Cntl.SizeChanged, AddressOf resetsub
RemoveHandler Cntl.StyleChanged, AddressOf resetsub
RemoveHandler Cntl.SystemColorsChanged, AddressOf resetsub
RemoveHandler Cntl.TabIndexChanged, AddressOf resetsub
RemoveHandler Cntl.TabStopChanged, AddressOf resetsub
RemoveHandler Cntl.TextChanged, AddressOf resetsub
RemoveHandler Cntl.Validated, AddressOf resetsub
RemoveHandler Cntl.Validating, AddressOf resetsub_Validatingeventargs
RemoveHandler Cntl.VisibleChanged, AddressOf resetsub

Dim subcntl As Control
For Each subcntl In Cntl.Controls
Call DisposeHandlers(subcntl)
Next

End Sub
Friend Sub resetsub_Validatingeventargs(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)
'MsgBox("Validatingeventargs")
Call resetsub(Nothing, Nothing)
End Sub
Friend Sub resetsub_QueryContinueDrageventargs(ByVal sender As Object, ByVal e As System.Windows.forms.QueryContinueDragEventArgs)
'MsgBox("QueryContinueDrageventargs")
Call resetsub(Nothing, Nothing)
End Sub
Friend Sub resetsub_Painteventargs(ByVal sender As Object, ByVal e As System.Windows.forms.PaintEventArgs)
'MsgBox("Painteventargs")
Call resetsub(Nothing, Nothing)
End Sub
Friend Sub resetsub_mouseeventargs(ByVal sender As Object, ByVal e As System.Windows.forms.MouseEventArgs)
'MsgBox("mouseeventargs")
Call resetsub(Nothing, Nothing)
End Sub
Friend Sub resetsub_layouteventargs(ByVal sender As Object, ByVal e As System.Windows.forms.LayoutEventArgs)
'MsgBox("layouteventargs")
Call resetsub(Nothing, Nothing)
End Sub
Friend Sub resetsub_givefeedbackeventargs(ByVal sender As Object, ByVal e As System.Windows.forms.GiveFeedbackEventArgs)
'MsgBox("givefeedbackeventargs")
Call resetsub(Nothing, Nothing)
End Sub
Friend Sub resetsub_Drageventargs(ByVal sender As Object, ByVal e As System.Windows.forms.DragEventArgs)
'MsgBox("Drageventargs")
Call resetsub(Nothing, Nothing)
End Sub
Friend Sub resetsub_Keypresseventargs(ByVal sender As Object, ByVal e As System.Windows.forms.KeyPressEventArgs)
'MsgBox("Keypresseventargs")
Call resetsub(Nothing, Nothing)
End Sub
Friend Sub resetsub_Keyargs(ByVal sender As Object, ByVal e As System.Windows.forms.KeyEventArgs)
'MsgBox("Keyargs")
Call resetsub(Nothing, Nothing)
End Sub
Friend Sub resetsub(ByVal sender As Object, ByVal e As System.EventArgs)
' MsgBox("EventArgs")
AutohibernateTimerCounter = 0
End Sub

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

OK, so what you do is set-up a timer on the main form that you have, with an interval setting of 1 second, so it fires the event every second. This shouldn't slow the system down too much. In that timer's tick event, (first make sure that the AutoHibernateEnabled value is true), if so, you increment the AutoHibernateTimerCounter by 1 and check to see if its hit AutoHibernateTimerCounter_MaxValue. If it has, then run the DoSomething() function, because the user has definitely not had any intervention over that period.

What you also have to do is make sure that in the New() constructor of the form, call InstantiateHandlers(formname), which runs through all of the controls on the form and appoints handlers for every event that they have, pointing to the assigned function resetsub

OK, so what is happening here?
Well, when the form is loaded, the InstantiateHandlers routine runs through each of the controls on the form and sets up a handler for each control (and for the form itself). What is a handler? A handler is like a secondary event. When an event like Click() happens, the handler takes care of it, then it runs the handler associated with that controls click event.

What we want to do here is have a timer that increases a counter every second, and, if there is no user interaction, it runs the function that we want. So, we want the counter to reset itself whenever a control is used in any way. Therefore, we instantiate the handlers for all controls on a form, and also for the form itself. They will all point to the resetsub subroutine that resets the counter. So, when anyone clicks or drags or moves or enters text or whatever, the handler is fired that runs resetsub and resets the counter.

Meanwhile, back on the form, if this hasnt happened and the timer event has increased the counter to the maximum value, then we can say that there has been no user interaction over MaxValue seconds.

The only other things you need to know is:

It doesnt work for Main-Menu controls. The handlers will not fire. Blame this one on Microsoft.

Next, in the dispose (destructor) function, call DisposeHandlers to remove the handlers from the form, therefore freeing-up memory.

I hope this helps.


Daniel Carlsson said:
I made a small component for handling that before, the way I handled it was
to
call Application.AddMessageFilter on the component (in its constructor).
Then in the PreFilterMessage function I checked for the following messages:

WM_MOUSEMOVE (512)
WM_LBUTTONDOWN (513)
WM_RBUTTONDOWN (516)
WM_MBUTTONDOWN (519)
WM_KEYDOWN (256)

The only case I found where that wont trigger is if the user is moving
around in menus only.
I never wound up using it in live code so I never took the time to find how
to handle that.

It worked fairly well in all other cases though
Hope it helps
/Dan
 
Back
Top