user32: Add a test for PeekMessage((HWND)-1), make it pass under Wine.

Dmitry Timoshkov dmitry at codeweavers.com
Thu Jun 11 07:49:31 CDT 2009


---
 dlls/user32/message.c   |    2 +
 dlls/user32/tests/msg.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++
 server/queue.c          |   10 +++++++-
 3 files changed, 65 insertions(+), 1 deletions(-)

diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 0d82001..f4913e1 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -2034,6 +2034,8 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
     if (!(buffer = HeapAlloc( GetProcessHeap(), 0, buffer_size ))) return FALSE;
 
     if (!first && !last) last = ~0;
+    if (hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST || hwnd == HWND_BOTTOM)
+        hwnd = (HWND)-1;
 
     for (;;)
     {
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 0a59ae8..28b0420 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -11592,6 +11592,59 @@ static void test_defwinproc(void)
     DestroyWindow( hwnd);
 }
 
+static void test_PostMessage(void)
+{
+    static const struct
+    {
+        HWND hwnd;
+        BOOL ret;
+    } data[] =
+    {
+        { HWND_TOP /* 0 */, TRUE },
+        { HWND_BROADCAST, TRUE },
+        { HWND_BOTTOM, TRUE },
+        { HWND_TOPMOST, TRUE },
+        { HWND_NOTOPMOST, FALSE },
+        { HWND_MESSAGE, FALSE },
+        { (HWND)0xdeadbeef, FALSE }
+    };
+    int i;
+    HWND hwnd;
+    BOOL ret;
+    MSG msg;
+
+    hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL);
+    assert(hwnd);
+
+    flush_events();
+
+    PostMessage(hwnd, WM_USER+1, 0x1234, 0x5678);
+    PostMessage(0, WM_USER+2, 0x5678, 0x1234);
+
+    for (i = 0; i < sizeof(data)/sizeof(data[0]); i++)
+    {
+        memset(&msg, 0xab, sizeof(msg));
+        ret = PeekMessageA(&msg, data[i].hwnd, 0, 0, PM_NOREMOVE);
+        ok(ret == data[i].ret, "%d: hwnd %p expected %d, got %d\n", i, data[i].hwnd, data[i].ret, ret);
+        if (data[i].ret)
+        {
+            if (data[i].hwnd)
+                ok(ret && msg.hwnd == 0 && msg.message == WM_USER+2 &&
+                   msg.wParam == 0x5678 && msg.lParam == 0x1234,
+                   "got ret %d hwnd %p msg %04x wParam %08lx lParam %08lx instead of TRUE/0/WM_USER/0x1234/0x5678\n",
+                   ret, msg.hwnd, msg.message, msg.wParam, msg.lParam);
+            else
+                ok(ret && msg.hwnd == hwnd && msg.message == WM_USER+1 &&
+                   msg.wParam == 0x1234 && msg.lParam == 0x5678,
+                   "got ret %d hwnd %p msg %04x wParam %08lx lParam %08lx instead of TRUE/0/WM_USER/0x1234/0x5678\n",
+                   ret, msg.hwnd, msg.message, msg.wParam, msg.lParam);
+        }
+    }
+
+    DestroyWindow(hwnd);
+    flush_events();
+}
+
 START_TEST(msg)
 {
     BOOL ret;
@@ -11633,6 +11686,7 @@ START_TEST(msg)
     hEvent_hook = 0;
 #endif
 
+    test_PostMessage();
     test_ShowWindow();
     test_PeekMessage();
     test_PeekMessage2();
diff --git a/server/queue.c b/server/queue.c
index e603b16..2668fdf 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -648,6 +648,14 @@ static void reply_message( struct msg_queue *queue, lparam_t result,
     }
 }
 
+static int match_window( user_handle_t win, user_handle_t msg_win )
+{
+    if (!win) return 1;
+    if (msg_win == win) return 1;
+    if (win == (user_handle_t)-1 && !msg_win) return 1;
+    return 0;
+}
+
 /* retrieve a posted message */
 static int get_posted_message( struct msg_queue *queue, user_handle_t win,
                                unsigned int first, unsigned int last, unsigned int flags,
@@ -658,7 +666,7 @@ static int get_posted_message( struct msg_queue *queue, user_handle_t win,
     /* check against the filters */
     LIST_FOR_EACH_ENTRY( msg, &queue->msg_list[POST_MESSAGE], struct message, entry )
     {
-        if (win && msg->win && msg->win != win && !is_child_window( win, msg->win )) continue;
+        if (!match_window(win, msg->win) && !is_child_window( win, msg->win )) continue;
         if (!check_msg_filter( msg->msg, first, last )) continue;
         goto found; /* found one */
     }
-- 
1.6.2.4




More information about the wine-patches mailing list