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.
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();
public Form1()
{
InitializeComponent();
foreach (Control ctrl in this.Controls)
{
ctrl.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
}
watcher = new Thread(new ThreadStart(UpdateInactivity));
watcher.Start();
}
void ctrl_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
ResetInactivity();
}
private void Form1_Activated(object sender, EventArgs e)
{
focused = true;
ResetInactivity();
}
private void Form1_Deactivate(object sender, EventArgs e)
{
focused = false;
ResetInactivity();
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
ResetInactivity();
}
private void ResetInactivity()
{
inactivity = 0;
}
private void UpdateInactivity()
{
try
{
while (true)
{
Thread.Sleep(1000);
if (focused)
{
inactivity++;
if (progressBar1 != null)
{
progressBar1.Invoke(new UpdaterCallback(this.UpdateProgressBar));
}
}
}
}
catch (ThreadAbortException)
{
}
}
private void UpdateProgressBar()
{
progressBar1.Value = (int)(((double)inactivity / (double)timeout) * 100);
if (inactivity >= timeout)
{
this.Close();
}
}
protected override void WndProc(ref Message m)
{
switch (m.WParam.ToInt64())
{
case WM_LBUTTONDOWN :
case WM_KEYDOWN :
inactivity = 0;
break;
}
base.WndProc(ref m);
}
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.