Click here to Skip to main content
15,892,298 members
Please Sign up or sign in to vote.
4.00/5 (2 votes)
See more:
I have developed a windows application with one form in c#.net.
My requirement is this form should be closed when "user have to open this application and have not work on it some period of time" (like screen saver).
If you know how to do this please help me.

[edit]Urgency removed: It may be urgent for you, but it just annoys people and can slow a response.
Capitalisation, spelling, textspeak removed - OriginalGriff[/edit]
Posted
Updated 18-Feb-11 7:17am
v3

I am not sure whats the issue in implementation. Keep a timer control on the form and configure it for a given period. If user is not interacting for that given period then close the form/application.

If you want to open a screensaver or a new form, based on the time lapsed in the timer, you can do that too!
 
Share this answer
 
Comments
Manfred Rudolf Bihy 18-Feb-11 5:12am    
Less verbose than Griff's answer but still enough. 5+
Venkateswara Rao Reddipalli 18-Feb-11 6:29am    
I am using timer control for the first time.I am unable to do properly.I want to close my application in 15min if the user is not doing any activity in the application.Plz explain clearly and post a piece of code if any.
Sandeep Mewara 18-Feb-11 6:41am    
Good to know you are doing something new.

here, go ahead, read and learn:
http://msdn.microsoft.com/en-us/library/bb398865.aspx

Expecting people to provide code is not good. Further, I believe you should understand that you are here for help and should appreciate the help instead of being demanding.
Sergey Alexandrovich Kryukov 18-Feb-11 11:59am    
Good answer, even better that you did not provide code but motivated, so my 5.
However, I though OP should be advised not to use this "feature"; please see my Answer.
--SA
Sergey Alexandrovich Kryukov 6-Mar-11 18:47pm    
Sandeep, my first Question based on my idea of "Most Elegant and Comprehensive Solution of a Completely Useless Task" challenge is ready. The idea was first discussed on this page.
Please see: http://www.codeproject.com/Questions/165416/Completely-Useless-Challenge-Mouse-hating-UI.aspx
--SA
Set up a Timer in the form. Set it's interval to a shortish period: say thirty seconds.
Set up a DateTime. Whenever there is "activity" (however you define that) reset the DateTime to DateTime.Now.AddMinutes(30).
In the Timer Tick Event check the current time against the timeout period.
DateTime closeDownAt;
private void Activity()
   {
   closeDownAt = DateTime.Now.AddMinutes(30);
   }

private activityTimer_Tick(object sender, EventArgs e)
   {
   if (DateTime.Now >= closeDownAt)
      {
      Close();
      }
   }




"I used the above code but its not working.Did i need to change the timer interval.If so,how to change.I am using timer control for the first time.Plz explain clearly."

Did you hook up the Timer.Tick event? :laugh:
If not then in your Form Load event code:
Activity();
activityTimer.Interval = 30000;   //30 seconds in milliseconds
activityTimer.Tick += new EventHandler(activityTimer_Tick);
activityTimer.Start();
 
Share this answer
 
v2
Comments
Manfred Rudolf Bihy 18-Feb-11 5:10am    
That's what I would have said. 5+
Proposed as answer.
Sergey Alexandrovich Kryukov 6-Mar-11 18:50pm    
As we discussed how useless (and hostile) this feature would be, I put forward the idea of the "Most Elegant and Comprehensive Solution of a Completely Useless Task" challenge.

My first Question is ready now, called [Completely Useless Challenge]: Mouse-hating UI.
Please see: http://www.codeproject.com/Questions/165416/Completely-Useless-Challenge-Mouse-hating-UI.aspx

--SA
Venkateswara Rao Reddipalli 18-Feb-11 6:23am    
I used the above code but its not working.Did i need to change the timer interval.If so,how to change.I am using timer control for the first time.Plz explain clearly.
OriginalGriff 18-Feb-11 6:30am    
Answer updated
Venkateswara Rao Reddipalli 18-Feb-11 6:53am    
still i am not getting my solution.bcoz form will close with in 30 seconds either i am using my form.sorry i am no much in english,pls understand.
Big warning for you! You can easily do it, but don't! This is very disruptive application behavior, not really useful. Will scare users to death!

—SA
 
Share this answer
 
Comments
#realJSOP 18-Feb-11 12:03pm    
Important point - don't annoy the people that pay you money for your application.
Sergey Alexandrovich Kryukov 18-Feb-11 12:07pm    
Exactly. Thanks, John.
--SA
Nish Nishant 18-Feb-11 12:04pm    
Voted 5. Very good point.
Sergey Alexandrovich Kryukov 18-Feb-11 12:08pm    
Thanks, Nishant.
--SA
#realJSOP 18-Feb-11 15:02pm    
But I just had to try it myself... See my answer. :)
John's attempt got me interested too, so here's another way to do this. Instead of manually checking for mouse and keyboard activity, I take advantage of WM_IDLE.

Once again, I do not condone any apps that do this sort of thing, my code is merely an exercise in coding, mostly for fun.

Opinions welcome :-)

C#
public partial class Form1 : Form
{
  public Form1()
  {
      InitializeComponent();
  }

  private int timeOutMs = 5000;

  private Timer timer = new Timer();

  private void Form1_Load(object sender, EventArgs e)
  {
      timer.Interval = timeOutMs;
      timer.Tick += Timer_Tick;

      Application.Idle += Application_Idle;
  }

  void Timer_Tick(object sender, EventArgs e)
  {
      Close();
  }

  void Application_Idle(object sender, EventArgs e)
  {
      if (timer.Enabled)
      {
          timer.Stop();
      }

      timer.Start();
  }
}
 
Share this answer
 
v2
Comments
#realJSOP 18-Feb-11 15:33pm    
I had to dock you a point for using the Timer object. :)
Sergey Alexandrovich Kryukov 18-Feb-11 15:35pm    
John, you have to make an exclusion in this case...

But Nish, at least use System.Timers.Timer! Otherwise John will rant, and I'll support him...

--SA
#realJSOP 18-Feb-11 15:50pm    
The Timer object is the domain of VB programmers and beginners. I do not recognize their viability in ANY program.
Nish Nishant 18-Feb-11 15:59pm    
DirectX and XNA based games all use timers. The one timer considered not that great is the Winforms timer, but in my example, it's safe to use it as it's only expected to run accurately when the message queue is empty (which in this case will always be the case).
Sergey Alexandrovich Kryukov 18-Feb-11 17:13pm    
"All timers are useless, but some timers are more useless then others"
--George Orwell :-)
Here's a fairly complete solution. Just create a new test Winforms solution, add a few controls, like a textbox, radio buttons etc (essentially, something you can click on), and make sure you add a progreesbar, paste this code into the cs file, and add the iindicated form event handlers in the designer.

Do not misconstrue this answer as support for the overall idea of closing a form this way, but merely as a way to accomplish what you want to do. The only real reason I provided the code was because the activity detection idea could actually prove useful for other (more valid) reasons.

C#
public partial class Form1 : Form
{
    private const int WM_LBUTTONDOWN = 0x0201;
    private const int WM_KEYDOWN     = 0x0100;

    private int timeout    = 20;
    private int inactivity = 0;
    private Thread watcher = null;
    private bool focused   = true;

    public delegate void UpdaterCallback();

    //--------------------------------------------------------------------------------
    // constructor
    public Form1()
    {
        InitializeComponent();

        // enumerate controls and add a previewkeydown handler for each one
        foreach (Control ctrl in this.Controls)
        {
            ctrl.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
        }
        watcher = new Thread(new ThreadStart(UpdateInactivity));
        watcher.Start();
    }

    //--------------------------------------------------------------------------------
    // Handle all keystrokes in all child controls
    void ctrl_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
        ResetInactivity();
    }

    //--------------------------------------------------------------------------------
    // form gains focus
    private void Form1_Activated(object sender, EventArgs e)
    {
        focused = true;
        ResetInactivity();
    }

    //--------------------------------------------------------------------------------
    // form looses focus
    private void Form1_Deactivate(object sender, EventArgs e)
    {
        focused = false;
        ResetInactivity();
    }

    //--------------------------------------------------------------------------------
    // mouse move on the form
    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        ResetInactivity();
    }

    //--------------------------------------------------------------------------------
    // resets inactivity indicator to 0
    private void ResetInactivity()
    {
        inactivity = 0;
    }

    //--------------------------------------------------------------------------------
    // Thread delegate that controls the inactivity indicator
    private void UpdateInactivity()
    {
        try
        {
            while (true)
            {
                Thread.Sleep(1000);
                if (focused)
                {
                    inactivity++;
                    if (progressBar1 != null)
                    {
                        progressBar1.Invoke(new UpdaterCallback(this.UpdateProgressBar));
                    }
                }
            }
        }
        catch (ThreadAbortException)
        {
        }
    }

    //--------------------------------------------------------------------------------
    // update the progress bar
    private void UpdateProgressBar()
    {
        // calculate the percentage, and display it
        progressBar1.Value = (int)(((double)inactivity / (double)timeout) * 100);
        // close the form if necessary
        if (inactivity >= timeout)
        {
            this.Close();
        }
    }

    //--------------------------------------------------------------------------------
    // Look for a keydown or left mouse button down not already handled by form events
    protected override void WndProc(ref Message m)     
    {         
        switch (m.WParam.ToInt64())
        {
            case WM_LBUTTONDOWN :
            case WM_KEYDOWN :
                inactivity = 0;
                break;
        }          
        base.WndProc(ref m);     
    }

    //--------------------------------------------------------------------------------
    // Abort the thread so we don't try to execute the delegate after its been 
    // destroyed
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        watcher.Abort();
    }      
}


EDIT ==================

I'm stunned that after providing a COMPLETE solution to the answer, someone would vote this anything less than a 5.

EDIT ==================

Edited to include support for keydown in a focused child control.
 
Share this answer
 
v6
Comments
Sergey Alexandrovich Kryukov 18-Feb-11 15:08pm    
I'm the one who voted "4", John, I stunned myself as well :-)
You know, sometimes I write something as complete as this, so...
Let me explain what could present some little problems.

First and foremost, I have overridden WndProc very recently and think that it will not preview WM_KEYDOWN if input focus is grabbed by a focusable control on the form. To my surprise, the key event was not dispatched to this function (yes, I set KeyPreview as well). Could you test this situation? I might need to override some other message-processing method (I don't remember or know exactly at the moment). After a while, I'm going to test it again.

Secondly, I think your criterion for "activity" is too narrow. I think you should include any input at all, even a mouse scroll or even motion. False positive is not bad, false negative is.

And finally, you should have admitted you're just having fun, not aiming to solve the application task which should not be solved :-) I know, you already expressed you agreement on that.

Thank you very much,
--SA
#realJSOP 18-Feb-11 15:14pm    
Most forms don't have scroll activity, but if I had included a scrollable control, i would have added support for it. You're right, I was just having fun. To get around the keydown thing, you could enumerate controls and just add a single event handler for all text controls and catch the KeyDown event. The whole thing is a bad idea (for the stated outcome), and I'm pretty sure nothing like this would ever exist in a real app out in the wild. If the OP needs to add functionality, he's free to do so.
Sergey Alexandrovich Kryukov 18-Feb-11 15:27pm    
Or, yes, about distributing of the event handler down the hierarchy will solve the problem (I used to do it), but not completely. Imagine a new control is added, this event should also be handled to add your "activation" event. Not so trivial as it seems, right? And this trick would defeat the purpose of WndProc. Well, scrolling is just one example, I did not mean scrolling but mouse activity over the form.

I agree OP should do the stuff (or, we already agree, should NOT).

I only said I managed to justify my "4" not "5", as you claimed a complete solution, but I found it was not quite.

OK?
Thank you for fun exercise :-)
--SA
#realJSOP 18-Feb-11 15:29pm    
I added support for keypress in a child control.
Nish Nishant 18-Feb-11 15:21pm    
Hey John, check out my alternative approach to doing this :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900