2013-08-19 139 views
1

我无法使PeekMessage正常工作。其实我希望它用信息泛滥我,但它的返回值是0.WinApi - PeekMessage始终返回False

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

(感谢给我看我做了错误)

+0

根据您的代码,您不会在该线程上创建窗口。你为什么期望线程队列中有消息? – Noseratio

+0

@Noseratio不需要线程拥有任何窗口来接收消息。毕竟有['PostThreadMessage'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx)。 – IInspectable

+0

@IInspectable,我没有看到在上面的代码中的任何地方。这就是为什么我问OP为什么期待消息泛滥的原因。 – Noseratio

回答

1

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

4

当您通过NULL(即0)对于hWnd参数,PeekMessage函数检索线程消息以及属于当前线程的任何窗口的消息。这在the documentation明确调用出:

的hWnd [在,可选]

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

如果hWnd为NULLPeekMessage检索消息对于属于当前线程的任何窗口,并且对当前线程的消息队列,其HWND值为NULL任何消息(见MSG结构)。因此,如果hwndNULL,则处理窗口消息和线程消息。

既然你调用一个线程池一个新线程功能,还有用它获取任何消息。该线程不与任何窗口关联并且没有消息。

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

如果您在主UI线程(与窗体关联的那个线程)上调用PeekMessage,您将看到所有发往窗体窗口的消息。

+0

嗯,我实际上读过这个线程注释,但是因为每个窗口都有它自己的线程,所以我很困惑1个线程可以如参数注释所示那样查看其他窗口的消息。我只想通过PeekMessage记录所有消息,并让它们由API本身进行翻译。 – Bitterblue

+0

@mini每个窗口都不*有*自己的线程。事实上,一般情况几乎恰恰相反:每个窗口都在* single *线程上运行;它被称为UI线程。为了回答你的其他问题,一个线程可以通过传入感兴趣的窗口的句柄来查看其他窗口的消息。 –

+1

PeekMessage不是一个很好的日志记录机制,当然不是你如何使用它。有更好的方法去做,但这是一个完全不同的问题。如果你问了,我会回答那个问题。谨防[XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。 –