3

I have a problem while doing this in the code-behind file of a winform :

// Waiting Cursor + disabling form
Cursor = Cursors.WaitCursor;
this.Enabled = false;

// Synchronous method
SomeWork();

// Re-enabling form
Cursor = Cursors.Default;
this.Enabled = true;

Current Behaviour

Clicking on a button for example during Somework() will execute the method associated to the button after re-enabling the form.

Expected Behaviour

I don't expect from the form to store the clicking events of the user while the form is disabled.

Question

Is there a way to empty the Clicking cache of the form (So that I'd do it before re-enabling the form) ?

IMPORTANT EDIT

A possible easy solution would be implementing the IMessageFilter interface in the code behind of the form. Disabling the left seems easy using this PreFilterMessage :

public bool PreFilterMessage(ref Message m)
{
    // Blocks all the messages relating to the left mouse button.
    return (m.Msg >= 513 && m.Msg <= 515) ;
}

But once again, disabling and re-enabling the mouse's left clicks DOES NOT EMPTY THE MOUSE BUFFER ...

Fares
  • 542
  • 1
  • 7
  • 17
  • The form can't receive any Click message when it's disabled. Are you sure? Could you provide more info on your demo, for example on what control did you click?... – King King Jul 30 '13 at 10:54

1 Answers1

1

The problem is that the process is running in the same thread, so the form doesn't actually get disabled before the process starts running. The easy thing to do would be use Application.DoEvents() to force it to set everything to disabled before starting the process, but the more professional (and probably safer) method is to run the time-consuming process in another thread.

NOTE: After running into another hitch in my own programming I found that you may have to run Application.DoEvents() before enabling everything again--it will fire any clicks the user made on the disabled controls, instead of waiting for the process to complete--enabling the controls--and THEN firing the click.

Obviously DoEvents is messy and I should be using threads.

  • 1
    If you don't set the button.Enabled property to false, it will still register the click. The little piece of code above disables all controls on my form and they will not register clicks. I put it in the click event of a button that runs a long process, just before the process is run, and it works exactly as you are asking...I clicked on several other controls, buttons and such, during the process and nothing happened when it finished. What exactly is the problem with it? You may have to use `Application.DoEvents()` to make it set the controls to disabled BEFORE the process starts running. –  Jul 31 '13 at 14:10
  • `DoEvents()` does the trick indeed. But many comments say that this method is evil ... – Fares Jul 31 '13 at 14:39
  • You could also run the time-consuming process in another thread. `Application.DoEvents()` can be dangerous if you use it the wrong way. But it does have a purpose. The top comment on this is good reading: http://stackoverflow.com/questions/5181777/use-of-application-doevents –  Jul 31 '13 at 15:05
  • 1
    I edited my answer. Initially I was under the impression that your form had actually been set to disabled, but the controls were not. My bad--I haven't yet played with the Enabled property on a form itself, just individual controls, so I wasn't exactly sure what it did. If you're disabling everything while the process is running, it may be perfectly safe to use Application.DoEvents(). It would be just like using ShowDialog() and running the process from a dialog form. –  Jul 31 '13 at 16:44
  • Sure ! In fact, running the process in another thread was the initial idea. Afterwards, I found out that the threading solution was not the best one. That's because the process launches 4 / 5 threads at a time. So I had to wait for all threads to terminate to launch another end-user process. And that was definitely not easy to deal with. That's why I thought that it'd be a good idea if the form freezes .. – Fares Aug 01 '13 at 08:13