WinApi - PeekMessage始终返回False

时间:2013-08-19 15:09:34

标签: c# winforms winapi peekmessage

我无法让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工作或者至少要了解如何使用它)

(感谢您向我显示我犯的错误)

2 个答案:

答案 0 :(得分:4)

当您为NULL参数传递hWnd(即0)时,PeekMessage函数会检索线程消息以及属于当前线程的任何窗口的消息。这在the documentation中明确显示:

  

hWnd [in,optional]

     
    

要检索其消息的窗口句柄。该窗口必须属于当前线程。

         

如果hWnd为NULLPeekMessage将检索属于当前线程的任何窗口的消息,以及当前线程的消息队列中 hwnd 值为{的消息{1}}(请参阅MSG结构)。因此,如果 hWnd NULL,则会处理窗口消息和线程消息。

  

由于您在ThreadPool中的新线程上调用此函数,因此没有要检索的消息。该线程与任何窗口都没有关联,也没有消息。

当没有可用消息时,该函数返回NULL(即0)。

如果您在主UI线程(与您的表单相关联的线程)上调用FALSE,您将会看到发往表单窗口的所有邮件。

答案 1 :(得分:1)

窗口消息队列是每线程的,除非以某种方式关联(AttachThreadInput,窗口父关系...)