0

I have a rather large C# Forms application. There's an MdiParent which controls lots of MdiChilds. I also created a 'loading screen' which jumps always on top when the user opens forms which require some loading time.

The thing is, if there are exceptions, I usually use something like Messagebox.Show(ErrorNumber) in the catch, so the user knows what happened. When my loading screen is on, and a message box shows, it's impossible to click it.

I'd like to tweak this. Is there a way to put a function in my MdiParent (or somewhere else, as long as it's just once) so it runs code whenever a MessageBox is shown? This way, I can easily call a function to close my loading screen. There are probably other solutions, but I'd like to learn more about window handles, hooks, etc.

Cœur
  • 37,241
  • 25
  • 195
  • 267
rvgiesen
  • 11
  • 3
  • 1
    Although you might be eager to learn more about window handles and hooks, etc, you must also consider good coding practice. And I doubt whether your proposed method is a proper solution. – Mike de Klerk Aug 09 '13 at 08:23

2 Answers2

1

You can subscribe to the Application.EnterThreadModal event.

This will be raised each time your application is about to enter the modal state (for example, because it is about to display a message box).

Note that there is also a corresponding Application.LeaveThreadModal event.

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • In the MSDN article for EnterThreadModal, the example shows a MessageBox when the event occurs. I thought this would actively cause the event again, resulting in infinite MessageBoxes - but I just tried it, and it was only displayed once. Why is that? – Lars Kristensen Aug 09 '13 at 09:27
  • 1
    Update: I tried the same with LeaveThreadModal-event. In this case, it does result in infite MessageBoxes. Which is strange, since the Enter-event "didn't occur" - can anybody explain? – Lars Kristensen Aug 09 '13 at 09:33
1

I think this is an awful idea. Imho, instead of practicing such voodoo, you should fix the real issue, which is the way you handle exceptions. Fixed code might look like this:

catch(Exception ex)
{
    CloseLoadingScreen();
    MessageBox.Show(ErrorNumber);
}

I mean, you are free to explore window hooks and stuff, its just that you've picked a bad occasion.

Edit: I think the proper way to refactor your code is to implement an entity, which sole purpose will be notifying user about important stuff. This entity will have knowledge about loading screen state and other relevant stuff, and depending on this context will do a set of actions (show message box, write to log, close loading screen, etc.). Then you can use this entity whenever you need to send a notification. This way you won't need to go through all the catch statements whenever you want to alter notification logic. It can be made a singleton for easier access.

Nikita B
  • 3,303
  • 1
  • 23
  • 41
  • Yeah, but that would mean I'd have to change tons of exception codes... That's why I'm looking to solve this with one function. But you're right, I'm not handling exceptions very well atm. – rvgiesen Aug 09 '13 at 08:32
  • I agree on with Nikita's answer. I have inherited a rather large Winforms codebase, and I had to do something similar - I tried to do some magic with MDI, but it eventually caused more problems than solutions. In the end, I went through all the MessageBox.Show() and CustomForm.ShowDialog() calls throughout the codebase, and handled the issue "manually". – Lars Kristensen Aug 09 '13 at 08:34
  • @rvgiesen, well, you said it. You are not handling exceptions well. And the sooner you fix this issue, the better. The solution you suggested is not a fix, it is workaround, which will cost you eventually. – Nikita B Aug 09 '13 at 08:44
  • Okay, I'm staying on the safe side here and recoded all my catch blocks. Thanks! – rvgiesen Aug 09 '13 at 09:52