私は、よく説明されているGlobalAddAtomメソッドとRegisterHotKey PInvokeメソッドを使用して、いくつかのホットキーを登録するC#WinFormsアプリケーションに取り組んでいます。プログラムは最小化モードで起動し、システムトレイで実行されます。ホットキーメッセージの1つが受信されるたびに、プログラムはどのキーが押されたかに関するデータをキャプチャし、処理のために別のオブジェクトに渡します。これはしばらくの間比較的うまく機能しましたが、時々奇妙な振る舞いがあります。同じメッセージが複数回処理されたり、一部のメッセージが完全に欠落したりするようなものです。
広範なログを追加した後、ユーザーがホットキーの組み合わせ(たとえば、Win + C)を通常より少し長く押し続けるか、単に押し続けると、メッセージループで新しいホットキーメッセージが受信されていることがわかりました。前のメッセージの処理が完了する前。
今、私が見ているように、メッセージはUIスレッドで受信され(非表示になっている場合でも)、別のクラスのインスタンスへのブロッキング呼び出しによって処理されます。それが本当なら、現在最初のメッセージを処理している同じ関数に別のメッセージをどのように入れることができますか?これは、Win32の理解が不足しているために、頭を悩ませているところです。
2番目のメッセージは別のスレッドで受信されているように見えます。しかし、それが本当なら、それは私の処理クラスのどのインスタンスを呼び出していますか?
これを理解する助けがあれば大歓迎です!
簡単な例を次に示します。このコード...
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case MultipleClipboardsDialog.WM_HOTKEY:
HotKey hotKey = new HotKey(m.LParam);
Log.Debug("About to process hot key " + hotKey.ToString());
this.Processor.ProcessHotKey(hotKey);
Log.Debug("Finished processing hot key " + hotKey.ToString());
break;
default:
base.WndProc(ref m);
break;
}
}
...このような出力を生成します。
About to process hot key Win + C
About to process hot key Win + C
About to process hot key Win + C
Finished processing hot key Win + C