2012-01-13 17 views
1

私はWindowsメッセージを処理するために2つのスレッドを持っています。クライアント領域のキー入力/マウス入力(このスレッドはゲームロジックも処理します)と残りの1つは、ゲームを作成し、DefWindowProc()をブロックしてゲームをフリーズさせるメッセージです。Windows:2つのスレッドがメッセージを処理していますか?

どうすればこの問題を解決できますか?

+0

'DefWindowProc'は本当に「ブロック」していません...かなり高速です。ブロックする原因となるメッセージの例を挙げられますか? –

+0

既存のデザインをそのまま残しておき、代わりに低速の応答をバックグラウンドスレッドで実行して、ゲームがフリーズしないようにする方がよいでしょう。 –

+0

ウィンドウを移動またはサイズ変更する場合、DefWindowProcはマウスボタンを離すまでブロックします – Jonathan

答えて

3

Codyが書いたのとは逆に、あなたは確かに複数のスレッドからのメッセージを処理できます。しかし、これはカスタマイズ可能なすべてではありません。むしろ、ウィンドウにはスレッド親和性があります。各スレッドは、そのスレッドによって作成されたウィンドウに送信またはポストされたメッセージを受け取ります。ウィンドウのメッセージを他のスレッドに配信する方法はありません。あなたの特定の状況では

、なぜ独自の隠されたウィンドウとメッセージループを持つワーカースレッドを作成していませんか?メインウィンドウがメインスレッドで処理したくないメッセージを受信したときに、それを他のウィンドウにポストすると、そのスレッドはキューに入れられ、ワーカースレッドによって処理されます。

+0

ああ、違うことを暗示するつもりはありませんでした。おそらく私はそれを少し強調した。 UIのない​​スレッドでUI作業をしようとすると、多くの人が深刻な問題に陥るのを私は見てきました。 –

+0

まさに私が必要なもの – Jonathan

1

Windowsがすでに提供しているメッセージキューを処理するスレッドが1つだけ必要です。計算上重いものは、CreateThreadで新しいものを作成して別のスレッドにディスパッチする必要があります。あなたが常にこれをやっていると分かったら、そのスレッドを永久にそこに持っていますが、必要なときに作業をするように通知してください。

1

いいえ、すべてのメッセージを1つのスレッドで処理する必要があります。この1つのスレッドは、ユーザーインターフェイスを制御するスレッドであるため、UIスレッドと呼ばれることがあります。 UI以外のスレッドでUIメッセージを処理しようとすると、問題が発生します。

しかし、一般的な問題は、特定のメッセージに応じて、長時間実行、計算集約タスクを実行するアプリケーションです。コードがメッセージハンドラの内部で実行されているときに、アプリケーションが他のメッセージ(スレッドは一度に1つしか処理できません)を処理することができず、UIが応答しなくなるため、これはうまくいきません。

ソリューションは、別のスレッドをスピンオフ(または2つまたはしかしあなたが必要とする多くの)と、そのスレッドにオフ長時間実行、計算集約タスクを委任することです。単一のUIスレッドでメッセージを処理しますが、メッセージハンドラの内部では、タスクをヘルパースレッドに渡します。 「ワーカースレッド」パターンまたは「バックグラウンドスレッド」パターンと呼ばれることがよくあります。

CreateThread functionを使用して追加のスレッドを作成できます。サンプルhereが見つかります。この場合

QueueUserWorkItem functionは単純オプションであるかもしれないように、それが聞こえます。サンプルコード:

DWORD CALLBACK ThreadProc(LPVOID p) 
{ 
    HWND hWnd = reinterpret_cast<HWND>(p); 

    for (int i = 0; i < 100000; ++i) 
    { 
     // do whatever 
    } 

    return 0; 
} 

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (uMsg) 
    { 
     case WM_KEYDOWN: // or whatever message you want to respond to 
     { 
      QueueUserWorkItem(ThreadProc, hWnd, WT_EXECUTELONGFUNCTION); 
      return 0; 
     } 
     // process other messages... 
    } 
    return DefWindowProc(hWnd, uMsg, wParam, lParam); 
} 

Win32スレッドプールでの読み取りは、hereです。

+1

複数のUIスレッドを持つことはできますが、各ウィンドウはメッセージが配信されるスレッドが1つのみに関連付けられています。 –

関連する問題