1

PeekMessage を動作させることができません。実際には、メッセージが殺到することが予想されますが、戻り値は 0 です。

私は WinForm を使用し、メッセージを覗くバックグラウンド スレッドを開始し、マウスでウィンドウを使用します。ウィンドウはいつものように使用できますが、メッセージをのぞくことができません。私は何を間違っていますか?最後のエラーは常に 0 です。

[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
    public IntPtr handle;
    public uint msg;
    public IntPtr wParam;
    public IntPtr lParam;
    public uint time;
    public Point p;
    public override string ToString()
    {
        return handle + ", " + msg + ", " + wParam + ", " + lParam + ", " + time + ", " + p;
    }
}

[DllImport("user32.dll")]
public static extern int PeekMessage(out NativeMessage lpMsg, IntPtr window, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);

public Form1()
{
    ThreadPool.QueueUserWorkItem(o => run());
}

private void run()
{
    for (int i = 0; i < 1000000; )
    {
        NativeMessage a = new NativeMessage();
        int c = PeekMessage(out a, IntPtr.Zero, (uint) 0, (uint) 0, (uint) 0);
        if (c != 0)
            trace(" -> " + c); // prints strings
    }
}

解決済み:

  • Show()フォームを表示するためにメインスレッドを呼び出しました
  • メインスレッドをリダイレクトしてメッセージをログに記録しました
  • (XY の問題ではなく、PeekMessage が機能するか、少なくとも使用方法を理解する必要がありました)

(私が犯したエラーを教えてくれてありがとう)

4

2 に答える 2

6

パラメータにNULL0を渡すと、関数はスレッド メッセージと、現在のスレッドに属するウィンドウのメッセージを取得します。これは、ドキュメントで明示的に呼び出されます。hWndPeekMessage

hWnd [入力、オプション]

メッセージを取得するウィンドウへのハンドル。ウィンドウは現在のスレッドに属している必要があります。

hWnd が の場合、現在のスレッドに属するウィンドウのメッセージと、現在のスレッドのメッセージ キューにあるhwnd値がであるメッセージ(構造体を参照)NULLを取得します。したがって、hWndがの場合、ウィンドウ メッセージとスレッド メッセージの両方が処理されます。PeekMessageNULLMSGNULL

ThreadPool の新しいスレッドでこの関数を呼び出しているため、取得するメッセージはありません。そのスレッドはどのウィンドウにも関連付けられておらず、メッセージもありません。

FALSE利用可能なメッセージがない場合、関数は (つまり 0) を返します。

メインの UI スレッド (フォームに関連付けられているスレッド)で呼び出しPeekMessageていた場合、フォーム ウィンドウ宛てのすべてのメッセージが表示されます。

于 2013-08-19T15:17:52.433 に答える
2

AttachThreadInputウィンドウ メッセージ キューは、何らかの方法で関連付けられていない限り (ウィンドウの親関係など)、スレッドごとです。

于 2013-08-19T15:17:15.543 に答える