From acb05666bbfd4814ee6fef59d8c59e716e4062d9 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 11 Jun 2009 21:49:31 +0900 Subject: [PATCH] user32: Add a test for PeekMessage((HWND)-1), make it pass under Wine. --- dlls/user32/message.c | 2 ++ dlls/user32/tests/msg.c | 54 +++++++++++++++++++++++++++++++++++++++++ server/queue.c | 10 +++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 0d820011542..f4913e1b343 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 0a59ae8b55f..28b0420b8a0 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 e603b16972b..c5841c939be 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 (win == (user_handle_t)-1) return !msg_win; + if (msg_win == win) return 1; + return is_child_window( win, msg_win ); +} + /* 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 )) continue; if (!check_msg_filter( msg->msg, first, last )) continue; goto found; /* found one */ }