views:

87

answers:

3

Some of our non-technical users are having problems where a dialog MessageBox in our application can sometimes be displayed behind the main form and the application does not accept any input until the messagebox (which they can't see) is dismissed.

The application is written in C# and the message boxes are standard eg the code can be as simple as MessageBox.Show(message, caption) and the messageboxes can be created by the main UI thread (ie not some background thread). The Application does not have to be run full-screen, but 90% of our users do run it full-screen.

Most of the time ((maybe > 99%) the messageboxes display correctly and I have never managed to see how it goes wrong, but I have seen a machine when it has gone wrong.

One thing I did notice is that if you have an application which displays a dialog box, then when you look at your taskmanager, you normal only see one entry in the application list. Whenever the messagebox is hidden, you will see two entries, one for the main application and another entry for this message box.

It is easy enough to fix the problem once you know what has happened, but some of our non-technical users are confused by it and end up switching off their computers. (And the ones who are using Remote Desktop are even more confused when that doesn't solve the problem).

I do not think it is related to the operating system as I have seen it happen in Vista and have been told it also happens in a terminal session on a Windows 2003 server.

Does anything know why this is happening and more importantly if anything can be done to avoid it?

+2  A: 

Some overloads of the MessageBox.Show() method take an IWin32Window parameter as the first argument. If you pass in your Form as that first argument it should prevent this from happening.

nukefusion
+1 for specifying the parent window. OP's problem most probably means that the message box has a null parent (i.e. desktop window) and sometimes this window ends up in the background.
casablanca
Is there any way of determining what the parent of the message box is (at runtime and on a customer's machine)?
sgmoore
http://www.catch22.net/software/winspy can tell you.
Kharlos Dominguez
A: 

You say "the messageboxes can be created by the main UI thread", which I assume means they aren't always created by the main UI thread. Your problem sounds like MessageBox.Show is occasionally called from another thread.

MusiGenesis
Nope, What I meant was that although some of the times it has occurred has been with messageboxes created by background thread, it also occurs on message boxes that are definitely created by the main UI thread.
sgmoore
Are you doing anything funky in your form? Like PInvoking SetWindowPos or anything like that?
MusiGenesis
No. The only usual thing is ShowInTaskbar is set false before the mainform is actually displayed whilst a Splash Screen is displayed and the program initialises. ShowInTaskbar is set true at the end of the Mainform Load event.
sgmoore
The fact that you're seeing two entries in task manager when this problem occurs means that the message box is not being shown from your UI thread (or that some other weirdness is going on).
MusiGenesis
I am certain it is called from my UI thread, but I would agree with you that some weirdness is going on. I also suspect that the message box starts off correctly linked and somehow later on the link is lost. I say that because I think (but am not 100% sure) that the problem occurs when they switch back to our application from using another application.
sgmoore
A: 

Is it always the same message box (for the same message?) coming the same form?

Ideally, you should try to find some way to reproduce the problem at will, or at least automatically. This will make your debugging easier and you can then be sure that your future change will have fixed the bug, rather than have to wait for a few weeks for the feedback from your users.

If it is always the same message and in the same window, resulting from the same action, and if the MessageBox call is reasonably easy to trigger from an user point-of-view and if your UI is relatively standard, you could automate the UI with an AutoIT script and have it run in a loop until the problem happens.

And/or, you could create a "debug"-build of your applications that you could give it to some users (preferably the ones that seem to run into the problem the most often) that would write the contents of a StackFrame object to a log file or something similar everytime before calling a MessageBox (you could create a wrapper around the MessageBox to make this easier).

Then, when one of your users gets the problem, you can look at the log file and see where it came from (source code file, line, calls stack etc). You could also compare this to the logs from other users and see if, everytime, the MessageBox comes from the same location or if it varies. This would show you where the problematic MessageBox is called from and where.

There may be easier solutions (especially if your application has a lot of assemblies) involving some .Net debugger that you would attach to your application when the problem occurs in order to see the call stack, etc, but I only did this with native applications (using OllyDbg) so far and not .Net. Others may be able to expand further on this idea...

Kharlos Dominguez
It is not always the same message and the messageboxes can be created from different parts of the program. However, the last time that I seen the message, I knew from the message where it was called from.The problem about try to automate it is that I think external factors come into place. When it was first reported, I thought it might be caused by the user minimising the application to work on another program and the message box being created whilst the application is minimised. But if I do that, whenever I switch back to my application, the message box is also displayed in front.
sgmoore
If you have ruled out the threading hypothesis already, I think you may need to rule out as many usual suspects as possible. Did you try running your application in a pristine machine (or VM)? Not sure how practical it is in your environment, but, though rare, it is not impossible that a utility or another software tries to steal the focus at some point or cause some weird things to happen with the windows. Also, it looks like you have never witnessed the bug first-hand.
Kharlos Dominguez
Also, if your users are in-house employees, and are ready to accept it, you could record their screen so you could watch what happened when they call you next time the issue occurs. That said, the fact they are observed may introduce some weird placebo effect in itself (if the user goes to websites while your application processes something, for example, and that they don't go anymore knowing you could watch the recording).
Kharlos Dominguez