Pergunta

I'm trying to write a simple program for my little brother. He's behind his computer a lot of times but he should be learning simple arithmetics for school :D

I want to make the following program:

  • He starts up his computer
  • He needs to do a few simple exercises and complete
  • If he did an x amount correct, he can continue to use his computer.

Is there a simple (it doesn't need to be very clean xD) way of locking his computer untill my program says it can do so.

P.S. (I don't mean locking as in the standard mechanism in windows)

P.P.S. It does't need to be super high tech, just that an average computer user cannot bypass it by closing the software :P

Foi útil?

Solução

You need some kind of system modal dialog (which isn't formally supported since win nt 4 (for some good reasons). However there is this blog that shows you how you can still accomplish the same thing.

Outras dicas

If this is stil relevant, then a simple way of locking down the computer for good without using any hooks is to do as follows:

First, create the Form_LostFocus Eventhandler. This isn't in the properties->events window, so you'll have to add it programmatically:

this.LostFocus += new ...

This is called when the from loses focus, so in here we need to give focus back to the form:

this.Focus();
this.Activate();

This method works best if focus is then given to a control on the form:

textBox1.Focus();

Next, add a timer, with an interval of 100ms, and enable it. This timer will check if the form has focus, and if not, will give it focus:

// in the Tick Eventhandler
if (!this.Focused)
    this.Focus();

This will effectively ensure that no matter what your user attemps to do, the program will always steal focus - even if he opens the task manager.

Then just make the program fullscreen: Set 'TopMost' property to true. Set 'WindowState' to 'maximised'. Set 'FormBorderStyle' to 'None'.

Finally, handle the Form_Closing Eventhandler.

// Global boolean value - set this to true when 
// the user has completed the set tasks
boolean complete = false;

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (!complete)
        e.cancel = true;
}

Please note: In general, stealing focus is extremely bad practice.

Look for inspiration at the code for babysmash, specifically here and here. It's an app for babies/toddlers written by Scott Hanselman that locks down the desktop reasonably well. You can probably reuse some of the ideas in there.

My solution for my son was to create a giant fullscreen wpf app with all the toolbars removed etc and load it on startup. Since there was no visible way to close it he had no idea how to close it, so would just go back to bed. He eventually learned how to get around it but it worked for him for a fair while.

It wasn't very hard to put together, and I could have implemented some more tactics to grab his screen input and stop it if he tried to close it but that wasn't needed by the time he figured out how to get around it.

With a fullscreen wpf app you should be able to output your math questions in an interesting format if you wish.

If you want something quick (although I think Eddy and jeroenh have quality answers) you can do it with no WinAPI/interop - just use window tricks.

First create a property HasCompletedTasks on your Form, set it to true when he has done his quizzes:

public bool HasCompletedTasks { get; set; }
public void CompleteAndClose()
{
    //if (File.Exists(_fileName))
    //    File.Delete(_fileName);
    HasCompletedTasks = true;
    Close();
}

Now prevent the window from closing:

protected override void OnClosing(CancelEventArgs e)
{
    base.OnClosing(e);
    e.Cancel = !HasCompletedTasks;
}

Next in the form designer set the FormBorderStyle to None, the WindowState to Maximized and TopMost to True, or just paste this code right under InitializeComponent();:

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
this.TopMost = true;

// const string MonitorFolder = "C:\\TasksNotDone";
// Directory.CreateDirectory(MonitorFolder);
// _fileName = Path.Combine(MonitorFolder, DateTime.Now.ToFileTimeUtc().ToString() + ".txt");
// File.WriteAllText(_fileName, DateTime.Now.ToString());

If you want to be alerted if he figures out how to close it (CTRL+ALT+DEL) you can leave files on the system that you can look for (and scold him accordingly). Uncomment the lines in samples to enable this.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top