C# WinApi-Peek消息始终返回False
我不能去上班。实际上,我希望它能给我大量的消息,但它的返回值是0 我使用WinForm,启动一个正在偷看消息的后台线程,并使用鼠标打开窗口。窗口可以像往常一样使用,但不能偷看任何消息。我做错了什么?最后一个错误始终为0C# WinApi-Peek消息始终返回False,c#,winforms,winapi,peekmessage,C#,Winforms,Winapi,Peekmessage,我不能去上班。实际上,我希望它能给我大量的消息,但它的返回值是0 我使用WinForm,启动一个正在偷看消息的后台线程,并使用鼠标打开窗口。窗口可以像往常一样使用,但不能偷看任何消息。我做错了什么?最后一个错误始终为0 [StructLayout(LayoutKind.Sequential)] public struct NativeMessage { public IntPtr handle; public uint msg; public IntPtr wParam;
[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
}
}
[StructLayout(LayoutKind.Sequential)]
公共结构NativeMessage
{
公共IntPtr句柄;
公共信息;
公共IntPtr wParam;
公共IntPtr LPRAM;
公共时间;
公共点p;
公共重写字符串ToString()
{
返回句柄+”、“+msg+”、“+wParam+”、“+lpram+”、“+time+”、“+p;
}
}
[DllImport(“user32.dll”)]
公共静态外部int PeekMessage(out NativeMessage lpMsg、IntPtr窗口、uint wMsgFilterMin、uint wMsgFilterMax、uint WremoveMG);
公共表格1()
{
QueueUserWorkItem(o=>run());
}
私家车
{
对于(int i=0;i<1000000;)
{
NativeMessage a=新的NativeMessage();
int c=PeekMessage(输出a,IntPtr.0,(uint)0,(uint)0,(uint)0);
如果(c!=0)
跟踪(“->”+c);//打印字符串
}
}
已解决:
- 我在主线程中调用了
,以显示我的表单Show()
- 并重定向主线程以记录消息
- (不是XY问题,我需要Peek消息来工作,或者至少要了解如何使用它)
(感谢您向我显示我犯的错误)窗口消息队列是每个线程的,除非以某种方式关联(
AttachThreadInput
,窗口父关系…)窗口消息队列是每个线程的,除非以某种方式关联(AttachThreadInput
,窗口父关系…)当您为hWnd
参数传递NULL
(即0)时,PeekMessage
函数检索线程消息以及属于当前线程的任何窗口的消息。这在以下章节中明确指出:
hWnd[输入,可选]
要检索其消息的窗口的句柄。窗口必须属于当前线程
如果hWnd为NULL
,PeekMessage
检索属于当前线程的任何窗口的消息,以及当前线程消息队列中hWnd值为NULL
的任何消息(请参见结构)。因此,如果hWnd为NULL
,则同时处理窗口消息和线程消息
由于您是在线程池中的新线程上调用此函数,因此没有要检索的消息。该线程不与任何窗口关联,也没有消息
当没有可用消息时,函数返回FALSE
(即0)
如果您在主UI线程(与窗体关联的线程)上调用
peek消息
,您将看到发送给窗体窗口的所有消息。当您为hWnd
参数传递NULL
(即0)时,peek消息
函数将检索线程消息,和属于当前线程的任何窗口的消息。这在以下章节中明确指出:
hWnd[输入,可选]
要检索其消息的窗口的句柄。窗口必须属于当前线程
如果hWnd为NULL
,PeekMessage
检索属于当前线程的任何窗口的消息,以及当前线程消息队列中hWnd值为NULL
的任何消息(请参见结构)。因此,如果hWnd为NULL
,则同时处理窗口消息和线程消息
由于您是在线程池中的新线程上调用此函数,因此没有要检索的消息。该线程不与任何窗口关联,也没有消息
当没有可用消息时,函数返回FALSE
(即0)
如果您在主UI线程(与表单关联的线程)上调用
PeekMessage
,您将看到发送到表单窗口的所有消息。根据您的代码,您不会在该线程上创建窗口。为什么希望线程队列中有任何消息?@Noseratio线程不需要拥有任何窗口来接收消息。毕竟有。@IInspectable,我在上面的代码中没有看到。这就是为什么我问OP为什么会出现大量消息。@如果打印所有发布到WndProc的消息,这将是一个相当大的洪水。@mini me,正确,但您没有在run()
线程内创建窗口,是吗?至少在上面的代码中没有。一个线程不能输出发布到属于另一个线程的窗口的消息。另外,在我看来,在消息循环中使用池线程并不是一个好主意。您应该创建一个新的子线程。根据您的代码,您不会在该线程上创建窗口。为什么希望线程队列中有任何消息?@Noseratio线程不需要拥有任何窗口来接收消息。毕竟有。@IInspectable,我在上面的代码中没有看到。这就是为什么我问OP为什么会出现大量消息。@如果打印所有发布到WndProc的消息,这将是一个相当大的洪水。@mini me,正确,但您没有在run()
线程内创建窗口,是吗?至少在上面的代码中没有。一个线程不能输出发布到属于另一个线程的窗口的消息。另外,在我看来,在消息循环中使用池线程并不是一个好主意。你应该创建一个新的子线程。嗯,我实际上读过线程注释,但是由于每个窗口都有自己的线程,我很困惑为什么一个线程可以在参数注释状态下偷看其他窗口的消息。我只想