WinApi - PeekMessage Always Returns False

4.8k views Asked by At

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)

2

There are 2 answers

0
Medinoc On BEST ANSWER

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

3
Cody Gray - on strike On

When you pass NULL (i.e. 0) for the hWnd parameter, the PeekMessage function retrieves thread messages, and messages for any window that belongs to the current thread. This is called out explicitly in the documentation:

hWnd [in, optional]

A handle to the window whose messages are to be retrieved. The window must belong to the current thread.

If hWnd is NULL, PeekMessage retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL (see the MSG structure). Therefore if hWnd is NULL, both window messages and thread messages are processed.

Since you are calling this function on a new thread in a ThreadPool, there are no messages for it to retrieve. That thread is not associated with any windows and has no messages.

The function returns FALSE (i.e. 0) when there are no messages available.

If you were calling PeekMessage on the main UI thread (the one associated with your form), you would be getting a peek at all messages destined for your form window.