2011-12-26 12 views
3

「スレッド入力キュー」とは何ですか?私はそれがMSDNで数回言及されていることを見てきました。そして、単にウィンドウのメッセージキューであるのか、それともそれらが意味するスレッドによって作成されたのか不思議に思うのを止めることができます。スレッド入力キュー

例:

WH_MOUSE_LLフックがあなたを約 がスレッド入力キューに掲載されるように、マウスの入力イベントを監視することができます。

+0

私は1990年代に学んだことは、DOSのキーボードバッファーに似ていることです - ユーザーがプロセスよりも速く入力すると、OSは入力(マウス、キーボード)をキューに入れます彼らは迷子にならない。 –

+0

@UweKeim、それはおおまかに言えば、マウスを左クリックすると、イベントがスレッド入力キューに最初に追加されます。デキューされ、それを実行すると、WM_LBUTTONDBLCLKというメッセージが作成され、それを特定のウィンドウのメッセージキューにエンキューします。 - つまり、マウスイベントをエンキューするためには、スレッド入力キューを最初に実行する必要があります。それは論理ですか?それとも間違っていますか? – ebb

+0

はい、私はそれを私の心の中に描いています。私はここで "スレッド"と "ウィンドウ"がどのように異なっているのか完全にはっきりしていませんが、誰かがさらに詳細な回答を投稿してくれることを確信しています:-) –

答えて

2

まず、ウィンドウに個別のメッセージキューがないことに注意してください。ウィンドウのメッセージは、関連するスレッドのメッセージキューに格納されます。

According to MSDNキーボードおよびマウス入力メッセージは、関連するウィンドウに関連付けられたスレッドのメッセージキューに送信されます。だから、私は "スレッドの入力キュー"は単に "スレッドのメッセージキュー"を言う別の方法だと思います。

EDIT:Raymondは、AttachThreadInput関数を使用して、入力を別のスレッドのメッセージキューにリダイレクトできることを指摘しました(コメントを参照)。したがって、「スレッド入力キュー」は、指定されたスレッドの入力を受信して​​いるメッセージキューを意味します。デフォルトではこれは同じスレッドのメッセージキューですが、別のスレッドのメッセージキューでもかまいません。

+2

各スレッドにはメッセージキューがあります。各スレッド*グループ*には入力キューがあります。 –

+0

@ RaymondChen、それを説明するどこかのドキュメント? – ebb

+1

16ビットビューについては、Bob Gundersonの「GetMessageおよびPeekMessage内部」を参照してください。 Win16では、システム全体で1つの入力キューがありますが、Win32では各スレッドグループに独自の入力キューがあります。 (スレッドグループはAttachThreadInput関数で作成されていますが、その関数が何であるか疑問に思っていましたか?)「Win32プログラマが知っておくべき5つのこと」も参照してください。 –

0

実際の答えは、論理抽象度offered by the MSDNよりも少し複雑です。私は、受け入れられた答えのコメントで確認されているものよりも詳細に答えることができます。

はい、2組のメッセージがあります。 「投稿メッセージキュー」と「入力メッセージキュー」があります。後者には、生のマウスとキーボードのメッセージイベントのリストが含まれています。前者には投稿された合成メッセージが含まれています。

内部的には両方ともリストにすぎませんが、入力メッセージリストは内部的に「入力キュー」と呼ばれる大きな構造体に含まれています。この構造体には、論理キューに関するデータと、生の入力メッセージリストのポインタが含まれています。

これらは、それぞれ「アプリケーションキュー」と「システムキュー」と交換することもできます。

GetMessage()はそれらを別々に処理します。

THREADINFOには、ポストメッセージリスト/キューに直接ポインタが含まれています。これは、QS_POSTMESSAGEが設定されている場合にスキャンされます。

いずれかQS_INPUT又はQS_EVENTキュー像が設定されている場合、入力リスト/キューがTHREADINFOから初期キュー構造のポインタと、そのキュー構造から入力されたリストへのポインタを取得することにより走査されます。奇妙なことに、私は知っている。

QS_TIMERキューステータスフラグが設定されている場合、GetMessage()(またはPeekMessage())が実際に呼び出さ誰に「所属」と警告ステータスで最も古いタイマーを見つけるために、完全な非カーネルタイマリストのスキャンを起動する必要がありますGetMessage()。キューには実際にタイマーが起動されたことに関する情報は格納されません。それらが格納する関連情報のみは、QS_TIMERフラグとトリガーされたタイマーの数のカウントです(GetMessage()は、最後にトリガーされたタイマーのメッセージを合成した時点で、キューステータスをQS_TIMERキューから消去するタイミングを認識します)。)

他の合成されたメッセージは、キューメッセージの実際のリストの外側に格納されたデータに基づいていますが、キュー構造自体の他のデータの "in"にも似ています。

関連する問題