2009-06-10 18 views
4

私は.NETとWindowsを初めて使いました。レガシーコードをC#プロジェクトに統合する方法を理解しようとしています。コード所有者は、「メッセージポンプ」と「アイドル処理」だけが必要だと言った。「メッセージポンプ」は1つだけか、それとも多くありますか?

グーグルでは、少なくともMFCWindows FormsWin32にはそれぞれ独自のメッセージポンプが搭載されているようですね。これは本当ですか?

私のC#のコードは、私はまったくのメッセージポンプを持っていません理解してコンソールアプリケーションです。私はそれらが単なるGUIのものだと思った(?)。

だから、私は彼が、彼は「メッセージポンプを」必要と言うとき、彼の古いコードを機能させるために、私のC#コードで行うには何が必要ですか?

私が使用する必要があるコードは、GUIアプリケーションで使用されています。今私は代わりにそれをサーバーで使用する必要があり、GUIのメッセージポンプの必要性について少し怖いです。私のコードは純粋なC#で、GUIのものはまったくありません。ちょうどいくつかの数のクランチとI/O。

答えて

8

メッセージとメッセージポンプに関する少しの背景から始めましょう。

Windowsでは、GUIアプリケーションはメッセージを処理することで動作します。たとえば、マウスを移動すると、WindowsはWM_MOUSEMOVEメッセージをマウスの下のウィンドウに送信します。

のWindowsポストウィンドウが属すると誰かが特定のウィンドウへのルートこのメッセージをしていることをスレッドの「メッセージ・キュー」へのメッセージ。誰かがメッセージポンプです。

すべてのWindows UIフレームワークは、メッセージポンプを持ち、かつ最も簡単なメッセージポンプはこのようになります(このコード例は、C++であり、あなたは.NETでそれを書くために相互運用機能を使用することができます):

MSG msg; 
while(GetMessage(&msg, hwnd, 0, 0)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

すべてのGUIプログラムにはメッセージポンプが必要ですが、コマンドラインプログラムは上記のコードを実行するだけでメッセージポンプを起動できます。明らかに、開いているウィンドウがないので、OSからのメッセージは表示されません。メッセージをキューに挿入するには、PostThreadMessageを使用します。

+0

http://msdn.microsoft.com/en-us/library/dd458656(VS.85).aspx また、アイドルハンドリングは、ヘルパー関数を頻繁に呼び出すという概念ですメサージキューが空のときにOnIdleと呼ばれます。通常、Onidleの下のルーチンは、ポンプをブロックしないようにすばやく戻る必要があります。通常、それはバックグラウンドタスクなどの完了を確認するために使用することができます – morechilli

+0

エルク、あなたが確認することはできません、彼はウィンドウを開くことがありますか、彼はWinForms(またはMFCまたは何でも)ただ知ることはできませんが、通常の方法で動作させたり、デバッグしたり、彼の癖を回避したりすることができます。 – Nir

2

あなたはそうです。 Windowsでは、メッセージポンプはそれ以上のもの(ホットキー通知など)で使用されていますが、「GUIのもの」です。

プロセスはスレッドごとにメッセージポンプを持つことができます。通常、これらは最初のウィンドウを作成するときに作成されます。コンソールアプリケーションにはメッセージポンプはありません。これを回避するには、Windows Formsウィンドウを作成し、それを不可視にします。

Application.Runを呼び出すと、Windowsフォームがメッセージポンプを起動します。あなたはそのウィンドウのHWNDを渡すことができ、おそらくそれをどうするかを知っているでしょう。返信されたメッセージをキャッチする場合は、フォームWndProcを上書きすることができます。これにより、そのウィンドウに送信されたメッセージのみがキャッチされます。

5

.NETでメッセージポンプを実行するには、Application.Run();と呼び出してください。これは、プログラムが終了メッセージを受信した場合にのみ実行を終了するブロッキング呼び出しです。 (通常、システムがシャットダウンしている場合)。通常、特定のイベントを待つ必要があるプログラムで使用されます。 (そして、もちろん、通常のGUIアプリケーションによって)

Application.Idleイベントを処理できます。

Windowsメッセージを処理する必要がある場合は、隠しフォームを作成し、WndProcメソッドをオーバーライドしてApplication.Runに渡すことができます。

これはサーバープロセスでもすべて実行できます。

+1

よかったです。だから私はこの古いコードを使用している場合(私はそれがCOMコンポーネントを使用してMFCを使用することができると思う)私は、Application.Run()を行う私の.NETアプリケーションでスレッドを生成するとうまく動作しますか? 私は自分の番号を他のスレッドで他のスレッドを実行していて、この古いライブラリをしばらく呼び出すと、メインループをクランチします。 MFCのOnIdldeで実行する必要のあるコードがこのライブラリにあるとします(これが実際にMFCコードの場合)。これもApplication.Runで処理されますか? –

+1

私は分かりません。それはコンポーネントが何をしているのか、どのように依存しているのですかおそらくスレッドセーフではありません。 スレッドでメッセージループを実行するには、STA(シングルスレッドアパートメント)スレッドである必要があります。スレッドを開始する前にThread.SetApartmentStateを呼び出します。 (または、メインスレッドの場合は、Main()メソッドの前に[STAThread]を追加します – SLaks

関連する問題