Search code examples
c#winformswinapipeekmessage

WinApi - PeekMessage Always Returns False


I can't get PeekMessage to work. Actually I would expect it to flood me with messages but it's return value is 0.

I use a WinForm, start a background thread that is peeking messages and use the window with the mouse. The window is usable like always but no messages can be peeked. What am I doing wrong ? Last error is 0 all the time.

[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
    }
}

Solved:

  • I called Show() in the main thread to show my form
  • and redirected the main thread to log the messages
  • (not XY problem, I needed PeekMessage to work or at least to understand how to use it)

(thanks for showing me the error I made)


Solution

  • Window message queues are per-thread unless associated in some way (AttachThreadInput, window parent relationship...)