0

The following code works as expected except that if the Form is "dragged" while disabled – when notepad exits – the Form will be in the new position. How can that be prevented?

Enabled = false;
Process p = Process.Start("notepad");
p.WaitForExit();
Enabled = true;
ispiro
  • 26,556
  • 38
  • 136
  • 291
  • 1
    This question/answer might be able to help you: http://stackoverflow.com/questions/907830/how-do-you-prevent-a-windows-form-being-moved – MAV May 24 '12 at 11:55
  • @MAV Thanks. But I wonder if there is some straightforward way, like some type of "complete" disabling a form (or some _simple_ flushing of the event que). – ispiro May 24 '12 at 12:03
  • @ispiro, as far as I know, capturing the WndProc messages and filtering out the 'MOVE' command in the MAV's linked question is about as direct as it gets. I dont know you'd want to blindly flush a forms message queue either. – hometoast May 24 '12 at 12:14
  • How you managed to drag the window while the form is disabled is very hard to guess. "Exists" is also very hard to understand, should it be "exits"? Improve your question. – Hans Passant May 24 '12 at 12:57
  • @HansPassant Look at my answer we have a bit of a discussion there, what he is saying is happening really is, it's sort of a bug I guess. If you drag Form1, while disabled, or a Form.ShowDialog is happening, when you return to the first Form by enabling it or Form2 returning a dialogresult, The First Form will move, to the location you tried to drag it too. Weird but true. – General Grey May 24 '12 at 13:01
  • @HansPassant Yes, "exists" was a typo. Fixed now to "exits". As for the "dragging": Do _as if_ you're dragging: press the mouse-button -> move the mouse -> let go of the button (So far nothing happened to the form). Then – when you close notepad – the form jumps to its new position. (This only happens if you minimize Visual Studio after you start debugging, but before closing notepad). – ispiro May 24 '12 at 13:05
  • Have you tried closing visual studio and running the app from the Exe? – General Grey May 24 '12 at 13:08
  • @K'Leg Good idea! But didn't work either. (Yes, I ran the .exe file. In fact, I even copied it to another location.) – ispiro May 24 '12 at 13:12
  • haha I tried it too, no luck. Where did @HansPassant go, he is good at this stuff – General Grey May 24 '12 at 13:15

2 Answers2

3

Okay, I repro the problem. The issue is that you are calling WaitForExit() on the UI thread. That stops it from pumping the message loop and processing input events. They will get put in the message queue. As soon as the process exits, your method returns and the UI thread starts pumping messages again. And finds the mouse messages that were buffered, executing them because the window is no longer disabled.

The general rule for code that runs on the UI thread is that it should never block. Lots of things will go wrong, this is just one example. It is easy to do with the Process class, it has an event that fires when the process exited. So you don't need to use WaitForExit(). Make your code look like this:

        this.Enabled = false;
        var prc = System.Diagnostics.Process.Start("notepad.exe");
        prc.EnableRaisingEvents = true;
        prc.SynchronizingObject = this;
        prc.Exited += delegate { 
            this.Enabled = true;
            this.Activate();
        };

Note that the Activate() call is necessary to put your window back into the foreground. This might not always work.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

You could try running Process start from a second Form called with a showDialog.

Form2 frm2 =new Form2();

frm2.ShowDialog();

in the Form2 Load event put your

Process p = Process.Start("notepad");
p.WaitForExit();
this.DialogResult=DialogResult.OK;

Have to check syntax on all that it is likely not perfect.

You could even set Form2.Visible to false, so the user never even sees it.

EDIT as HomeToast suggested, This works very well, as long as you don't mind Hiding your Form, If you want to keep your Form visible I would go with my first suggestion

In this Option, we are going to Visible=false the main form, instead if Enable=false If there is no Form to Drag, the user cannot drag it.

this.Visible = false;
Process p = Process.Start("notepad");
p.WaitForExit();
this.Visible = true;
General Grey
  • 3,598
  • 2
  • 25
  • 32
  • I tested this out and it works, except when you close Notepad, it Closes Form2 as expected, but Form1 seems to minimize. – General Grey May 24 '12 at 12:11
  • Actually I never even thought of that, I meant to hide Form2, but you are suggesting to Hide Form1, then the user could note modify it. I will add that as an edit, though @hometoast you deserve the credit for it. – General Grey May 24 '12 at 12:16
  • ha. not really my idea, your last sentence before the edit was: "You could even set Form2.Visible to false, so the user never even sees it. " But thank you – hometoast May 24 '12 at 12:20
  • Thanks for the answer. Nice thinking of this idea. Unfortunately, it doesn't work. – ispiro May 24 '12 at 12:40
  • The reason it seems to work for you (and to minimize the original form) is because somehow Visual Studio interferes with it. Try the following: after you start debugging – minimize all -> show the running form -> (opens notepad) -> "drag" form -> close notepad. – ispiro May 24 '12 at 12:41
  • You have to be doing something different because I can't "DRAG" the form, it is not an option for me, which one of my solutions did you try, because they are very different, or are you reffering to the Form Moving, after you close NotePad? – General Grey May 24 '12 at 12:47
  • That's why "drag" is in quotes – I mean: do _as if_ you're dragging: press the mouse-button -> move the mouse -> let go of the button (So far nothing happened to the form). Then – when you close notepad – the form jumps to its new position. – ispiro May 24 '12 at 12:51
  • Ok, you could have told us that was what you were trying to avoid in the first place. Try the second option then, it should solve all the problems. At least the ones you have told us about :) Actually I guess you did, I just didn't understand it, I apologize. – General Grey May 24 '12 at 12:52
  • What do you mean your 2nd option? I did make Form2 invisible, if that's what you mean. – ispiro May 24 '12 at 12:54
  • No, no, no, in the second option we are not using a second form. Back to your original code, when you enabled=false .... enabled.true change to Visible=false .... Visible=true, I will edit the answer to attempt to make it more clear. – General Grey May 24 '12 at 12:56
  • Oh, OK. That's simple enough if I would want to hide it. Unfortunately, I don't. But +1 anyway. :) – ispiro May 24 '12 at 12:59
  • I give up, this is weird, I can't seem to stop it. Hopefully someone else has an answer, because other than hiding it...... I got nothing – General Grey May 24 '12 at 13:12