[PATCH] user32: Set WM_CONTEXTMENU's wparam to the child window's handle

Huw Davies huw at codeweavers.com
Fri Jan 7 02:46:36 CST 2022


DefWindowProc() does not propagate the wparam; it updates it instead.
Spotted by YAL.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52327
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/user32/defwnd.c    |  2 +-
 dlls/user32/tests/msg.c | 29 +++++++++++++++++++++++++++--
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c
index 8cd9047f02b..44675c7b8e7 100644
--- a/dlls/user32/defwnd.c
+++ b/dlls/user32/defwnd.c
@@ -322,7 +322,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
 
     case WM_CONTEXTMENU:
         if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
-            SendMessageW( GetParent(hwnd), msg, wParam, lParam );
+            SendMessageW( GetParent(hwnd), msg, (WPARAM)hwnd, lParam );
         else
         {
             LONG hitcode;
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index c054a145112..870c38b106c 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -106,6 +106,7 @@ typedef struct
 } MEASURE_ITEM_STRUCT;
 
 static BOOL test_DestroyWindow_flag;
+static BOOL test_context_menu;
 static HWINEVENTHOOK hEvent_hook;
 static HHOOK hKBD_hook;
 static HHOOK hCBT_hook;
@@ -9984,7 +9985,7 @@ static LRESULT MsgCheckProc (BOOL unicode, HWND hwnd, UINT message,
         return 0;
     }
 
-    if (message == WM_CONTEXTMENU)
+    if (!test_context_menu && message == WM_CONTEXTMENU)
     {
         /* don't create context menu */
         return 0;
@@ -16148,6 +16149,13 @@ static const struct message WmRestoreActiveMinimizedOverlappedSeq[] =
     { 0 }
 };
 
+static struct message WmContextMenuSeq[] = {
+    { WM_CONTEXTMENU, sent|wparam, 0 }, /* wparams set in the code */
+    { WM_CONTEXTMENU, sent|wparam|defwinproc, 0 },
+    { WM_CONTEXTMENU, sent|wparam|defwinproc, 0 },
+    { 0 }
+};
+
 struct rbuttonup_thread_data
 {
     HWND hwnd;
@@ -16169,7 +16177,7 @@ static DWORD CALLBACK post_rbuttonup_msg( void *arg )
 
 static void test_defwinproc(void)
 {
-    HWND hwnd;
+    HWND hwnd, child[3];
     MSG msg;
     BOOL gotwmquit = FALSE;
     POINT pos;
@@ -16219,6 +16227,23 @@ static void test_defwinproc(void)
     flush_events();
     ok_sequence(WmRestoreActiveMinimizedOverlappedSeq, "DefWindowProcA(SC_RESTORE):active minimized overlapped", TRUE);
 
+    child[0] = CreateWindowExA(0, "TestWindowClass", "1st child",
+                               WS_VISIBLE | WS_CHILD, 0,0,500,100, hwnd, 0, 0, NULL);
+    child[1] = CreateWindowExA(0, "TestWindowClass", "2nd child",
+                               WS_VISIBLE | WS_CHILD, 0,0,500,100, child[0], 0, 0, NULL);
+    child[2] = CreateWindowExA(0, "TestWindowClass", "3rd child",
+                               WS_VISIBLE | WS_CHILD, 0,0,500,100, child[1], 0, 0, NULL);
+    flush_events();
+    flush_sequence();
+    test_context_menu = TRUE;
+    DefWindowProcA(child[2], WM_CONTEXTMENU, 0xcafe, 0);
+    test_context_menu = FALSE;
+    WmContextMenuSeq[0].wParam = (WPARAM)child[2];
+    WmContextMenuSeq[1].wParam = (WPARAM)child[1];
+    WmContextMenuSeq[2].wParam = (WPARAM)child[0];
+    ok_sequence(WmContextMenuSeq, "DefWindowProcA(WM_CONTEXTMENU)", FALSE);
+    DestroyWindow(child[0]);
+
     GetCursorPos(&pos);
     GetWindowRect(hwnd, &rect);
     x = (rect.left+rect.right) / 2;
-- 
2.23.0




More information about the wine-devel mailing list