1

ShowDialog()キーボード フック イベントがトリガーされたときに呼び出したいのですが、いくつか問題があります。

  • ShowDialog() はブロックするため、OS をブロックするため、フック トリガー イベントから呼び出すことはできません。
  • 新しいスレッドを開始してそこから呼び出すことはできますShowDialog()が、厄介な例外が発生します。ShowDialog()他のスレッドで呼び出すことはできないと思います。
  • タイマーを開始できます: 次の 50 ミリ秒の呼び出しShowDialog()で (これは厄介なハックであり、私はむしろこれを行いません)。しかし、新しいスレッドでタイマーが起動すると、前の箇条書きで説明したのと同じ問題に遭遇します。

方法はありますか?

4

6 に答える 6

2

問題は、UI を非 UI スレッドに入れようとしている可能性があります。別のスレッドからイベントを発生さShowDialog()せ、UI スレッドから実行されるメソッドを呼び出します。

基本的に、UI スレッドに UI を保持し、それ以外はすべてバックグラウンド スレッドに移動します。

詳細については、 Gekki Softwareを参照してください (他にも無数にある - これはたまたま研究アーカイブで最初に見つけたものです)。

于 2008-10-07T01:34:13.550 に答える
1

ShowDialog についてはよくわかりませんが、バックグラウンド スレッドで UI を操作しようとしたときに例外が発生した場合は、UI ディスパッチャを使用する必要があります。

showdialog を呼び出すデリゲートを使用して制御する任意の UI オブジェクトの BeginInvoke メソッド (Windows フォームを使用している場合) を呼び出してみてください。

また、(この前に) show dialog メソッドで有効な所有者への参照を渡すようにしてください。

于 2008-10-07T01:20:38.180 に答える
0

「厄介な例外」がなければ、何が起こっているのかわかりません。スレッドがSTAスレッドではなく、インスタンス化されたときに UI オブジェクトが例外をスローしているためだと思います。新しいスレッドのアパートメント モデルをMTAではなく STA に設定し、それが役立つかどうかを確認します。

違いが分からない場合は、Multithreaded Apartments (MSDN) などを読んでください。

于 2008-10-07T01:22:17.317 に答える
0

KeyPress タイプのイベントからダイアログを表示できるはずです。

また、ShowDialog()別スレッドから使​​用するとモーダルになりません(親なし)。を使用するのと同じShow()です。

于 2008-10-07T01:39:52.820 に答える
0

これを試して:

void MyKeyboardHookHandler(...)
{
     WindowsFormsSynchronizationContext.Current.Post(state =>
     {
         Form f = new Form();
         f.ShowDialog();
     }, null);
}
于 2008-10-07T02:54:03.170 に答える
-1

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.

于 2008-10-07T01:37:43.370 に答える