Question

I want to call ShowDialog() when a keyboard hook event is triggered, but I'm having some difficulties:

  • ShowDialog() blocks, so I can't call it from the hook triggered event, because it will block the OS.
  • I can start a new thread and call ShowDialog() from there, but I get some nasty exception. I guess I can't call ShowDialog() in any other thread.
  • I can start a timer: in the next 50 milliseconds call ShowDialog() (which is a nasty hack BTW, and I rather not do this). But then the timer fires in a new thread, and then I run into the same problem explained in the previous bullet.

Is there a way?

Was it helpful?

Solution

The problem may be that you are trying to put UI in a non-UI thread. Make your event fire from another thread and invoke the method that runs ShowDialog() from your UI thread.

Essentially, you want to keep your UI on the UI thread and move anything else to a back ground thread.

Check out Gekki Software for some details (there are zillions of others - this just happens to be the first one I found in research archives).

OTHER TIPS

I'm not sure about ShowDialog, but whenever you get an exception when trying to do something with the UI in a background thread, it means you should use the UI dispatcher.

Try calling the BeginInvoke method (if you are on Windows Forms) of any UI object you control with a delegate that calls the showdialog.

Also, make sure to try (before this) passing a reference to a valid owner in the show dialog method.

Try this:

void MyKeyboardHookHandler(...)
{
     WindowsFormsSynchronizationContext.Current.Post(state =>
     {
         Form f = new Form();
         f.ShowDialog();
     }, null);
}

You really should be able to show the dialog from a KeyPress type event.

Also, if you use ShowDialog() from another thread, it will not be modal (no parent). It would be the same as using Show().

Without the "nasty exception" it's hard to tell what's going on. I would assume it's because your thread isn't an STA thread, and the UI objects are throwing the exception when they get instantiated. Set your new thread's apartment model to be STA instead of MTA and see if that helps.

And if you don't know what the difference is, you should do some reading up, for instance Multithreaded Apartments (MSDN).

ShowDialog() will block your application's thread, but that's what it's supposed to do. If you don't want the form blocking your application, call Show() instead.

ShowDialog() will not "block the OS", so don't be reluctant to use it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top