[PATCH 09/13] win32u: Move NtUserTranslateAccelerator from user32.

Jacek Caban wine at gitlab.winehq.org
Mon May 2 05:44:42 CDT 2022


From: Jacek Caban <jacek at codeweavers.com>

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
---
 dlls/user32/menu.c           | 204 +------------------------
 dlls/user32/user32.spec      |   2 +-
 dlls/win32u/gdiobj.c         |   1 +
 dlls/win32u/menu.c           | 279 +++++++++++++++++++++++++++++++++++
 dlls/win32u/win32u.spec      |   2 +-
 dlls/win32u/win32u_private.h |   1 +
 dlls/win32u/wrappers.c       |   6 +
 7 files changed, 291 insertions(+), 204 deletions(-)

diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 9f51fa555f8..669d838bf61 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -56,7 +56,6 @@
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(menu);
-WINE_DECLARE_DEBUG_CHANNEL(accel);
 
 /* internal flags for menu tracking */
 
@@ -4768,170 +4767,6 @@ DWORD WINAPI CalcMenuBar(HWND hwnd, DWORD left, DWORD right, DWORD top, RECT *re
 }
 
 
-/**********************************************************************
- *           translate_accelerator
- */
-static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam,
-                                   BYTE fVirt, WORD key, WORD cmd )
-{
-    INT mask = 0;
-    UINT mesg = 0;
-
-    if (wParam != key) return FALSE;
-
-    if (NtUserGetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
-    if (NtUserGetKeyState(VK_MENU) & 0x8000) mask |= FALT;
-    if (NtUserGetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
-
-    if (message == WM_CHAR || message == WM_SYSCHAR)
-    {
-        if ( !(fVirt & FVIRTKEY) && (mask & FALT) == (fVirt & FALT) )
-        {
-            TRACE_(accel)("found accel for WM_CHAR: ('%c')\n", LOWORD(wParam) & 0xff);
-            goto found;
-        }
-    }
-    else
-    {
-        if(fVirt & FVIRTKEY)
-        {
-            TRACE_(accel)("found accel for virt_key %04lx (scan %04x)\n",
-                          wParam, 0xff & HIWORD(lParam));
-
-            if(mask == (fVirt & (FSHIFT | FCONTROL | FALT))) goto found;
-            TRACE_(accel)(", but incorrect SHIFT/CTRL/ALT-state\n");
-        }
-        else
-        {
-            if (!(lParam & 0x01000000))  /* no special_key */
-            {
-                if ((fVirt & FALT) && (lParam & 0x20000000))
-                {                              /* ^^ ALT pressed */
-                    TRACE_(accel)("found accel for Alt-%c\n", LOWORD(wParam) & 0xff);
-                    goto found;
-                }
-            }
-        }
-    }
-    return FALSE;
-
- found:
-    if (message == WM_KEYUP || message == WM_SYSKEYUP)
-        mesg = 1;
-    else
-    {
-        HMENU hMenu, hSubMenu, hSysMenu;
-        UINT uSysStat = (UINT)-1, uStat = (UINT)-1, nPos;
-        POPUPMENU *menu;
-
-        hMenu = (GetWindowLongW( hWnd, GWL_STYLE ) & WS_CHILD) ? 0 : GetMenu(hWnd);
-        hSysMenu = get_win_sys_menu( hWnd );
-
-        /* find menu item and ask application to initialize it */
-        /* 1. in the system menu */
-        if ((menu = find_menu_item(hSysMenu, cmd, MF_BYCOMMAND, NULL)))
-        {
-            hSubMenu = menu->obj.handle;
-            release_menu_ptr(menu);
-
-            if (GetCapture())
-                mesg = 2;
-            if (!IsWindowEnabled(hWnd))
-                mesg = 3;
-            else
-            {
-                SendMessageW(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L);
-                if(hSubMenu != hSysMenu)
-                {
-                    nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu);
-                    TRACE_(accel)("hSysMenu = %p, hSubMenu = %p, nPos = %d\n", hSysMenu, hSubMenu, nPos);
-                    SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE));
-                }
-                uSysStat = GetMenuState(GetSubMenu(hSysMenu, 0), cmd, MF_BYCOMMAND);
-            }
-        }
-        else /* 2. in the window's menu */
-        {
-            if ((menu = find_menu_item(hMenu, cmd, MF_BYCOMMAND, NULL)))
-            {
-                hSubMenu = menu->obj.handle;
-                release_menu_ptr(menu);
-
-                if (GetCapture())
-                    mesg = 2;
-                if (!IsWindowEnabled(hWnd))
-                    mesg = 3;
-                else
-                {
-                    SendMessageW(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L);
-                    if(hSubMenu != hMenu)
-                    {
-                        nPos = MENU_FindSubMenu(&hMenu, hSubMenu);
-                        TRACE_(accel)("hMenu = %p, hSubMenu = %p, nPos = %d\n", hMenu, hSubMenu, nPos);
-                        SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE));
-                    }
-                    uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND);
-                }
-            }
-        }
-
-        if (mesg == 0)
-        {
-            if (uSysStat != (UINT)-1)
-            {
-                if (uSysStat & (MF_DISABLED|MF_GRAYED))
-                    mesg=4;
-                else
-                    mesg=WM_SYSCOMMAND;
-            }
-            else
-            {
-                if (uStat != (UINT)-1)
-                {
-                    if (IsIconic(hWnd))
-                        mesg=5;
-                    else
-                    {
-                        if (uStat & (MF_DISABLED|MF_GRAYED))
-                            mesg=6;
-                        else
-                            mesg=WM_COMMAND;
-                    }
-                }
-                else
-                    mesg=WM_COMMAND;
-            }
-        }
-    }
-
-    if( mesg==WM_COMMAND )
-    {
-        TRACE_(accel)(", sending WM_COMMAND, wParam=%0x\n", 0x10000 | cmd);
-        SendMessageW(hWnd, mesg, 0x10000 | cmd, 0L);
-    }
-    else if( mesg==WM_SYSCOMMAND )
-    {
-        TRACE_(accel)(", sending WM_SYSCOMMAND, wParam=%0x\n", cmd);
-        SendMessageW(hWnd, mesg, cmd, 0x00010000L);
-    }
-    else
-    {
-        /*  some reasons for NOT sending the WM_{SYS}COMMAND message:
-         *   #0: unknown (please report!)
-         *   #1: for WM_KEYUP,WM_SYSKEYUP
-         *   #2: mouse is captured
-         *   #3: window is disabled
-         *   #4: it's a disabled system menu option
-         *   #5: it's a menu option, but window is iconic
-         *   #6: it's a menu option, but disabled
-         */
-        TRACE_(accel)(", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg);
-        if(mesg==0)
-            ERR_(accel)(" unknown reason - please report!\n");
-    }
-    return TRUE;
-}
-
 /**********************************************************************
  *      TranslateAcceleratorA     (USER32.@)
  *      TranslateAccelerator      (USER32.@)
@@ -4942,7 +4777,7 @@ INT WINAPI TranslateAcceleratorA( HWND hWnd, HACCEL hAccel, LPMSG msg )
     {
     case WM_KEYDOWN:
     case WM_SYSKEYDOWN:
-        return TranslateAcceleratorW( hWnd, hAccel, msg );
+        return NtUserTranslateAccelerator( hWnd, hAccel, msg );
 
     case WM_CHAR:
     case WM_SYSCHAR:
@@ -4952,45 +4787,10 @@ INT WINAPI TranslateAcceleratorA( HWND hWnd, HACCEL hAccel, LPMSG msg )
             WCHAR wch;
             MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1);
             msgW.wParam = MAKEWPARAM(wch, HIWORD(msg->wParam));
-            return TranslateAcceleratorW( hWnd, hAccel, &msgW );
+            return NtUserTranslateAccelerator( hWnd, hAccel, &msgW );
         }
 
     default:
         return 0;
     }
 }
-
-/**********************************************************************
- *      TranslateAcceleratorW     (USER32.@)
- */
-INT WINAPI TranslateAcceleratorW( HWND hWnd, HACCEL hAccel, LPMSG msg )
-{
-    ACCEL data[32], *ptr = data;
-    int i, count;
-
-    if (!hWnd) return 0;
-
-    if (msg->message != WM_KEYDOWN &&
-        msg->message != WM_SYSKEYDOWN &&
-        msg->message != WM_CHAR &&
-        msg->message != WM_SYSCHAR)
-        return 0;
-
-    TRACE_(accel)("hAccel %p, hWnd %p, msg->hwnd %p, msg->message %04x, wParam %08lx, lParam %08lx\n",
-                  hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam);
-
-    if (!(count = NtUserCopyAcceleratorTable( hAccel, NULL, 0 ))) return 0;
-    if (count > ARRAY_SIZE( data ))
-    {
-        if (!(ptr = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*ptr) ))) return 0;
-    }
-    count = NtUserCopyAcceleratorTable( hAccel, ptr, count );
-    for (i = 0; i < count; i++)
-    {
-        if (translate_accelerator( hWnd, msg->message, msg->wParam, msg->lParam,
-                                   ptr[i].fVirt, ptr[i].key, ptr[i].cmd))
-            break;
-    }
-    if (ptr != data) HeapFree( GetProcessHeap(), 0, ptr );
-    return (i < count);
-}
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index 298a0fa3150..26f2d1caf45 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -767,7 +767,7 @@
 @ stdcall TrackPopupMenuEx(long long long long long ptr)
 @ stdcall TranslateAccelerator(long long ptr) TranslateAcceleratorA
 @ stdcall TranslateAcceleratorA(long long ptr)
-@ stdcall TranslateAcceleratorW(long long ptr)
+@ stdcall TranslateAcceleratorW(long long ptr) NtUserTranslateAccelerator
 @ stdcall TranslateMDISysAccel(long ptr)
 @ stdcall TranslateMessage(ptr)
 # @ stub TranslateMessageEx
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c
index c5db1bfcc30..ad04ba7ff78 100644
--- a/dlls/win32u/gdiobj.c
+++ b/dlls/win32u/gdiobj.c
@@ -1224,6 +1224,7 @@ static struct unix_funcs unix_funcs =
     NtUserSystemParametersInfoForDpi,
     NtUserToUnicodeEx,
     NtUserTrackMouseEvent,
+    NtUserTranslateAccelerator,
     NtUserTranslateMessage,
     NtUserUnregisterClass,
     NtUserUnregisterHotKey,
diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c
index 8544cca47b4..d41aba956f2 100644
--- a/dlls/win32u/menu.c
+++ b/dlls/win32u/menu.c
@@ -235,6 +235,23 @@ static BOOL is_menu( HMENU handle )
     return is_menu;
 }
 
+/***********************************************************************
+ *           get_win_sys_menu
+ *
+ * Get the system menu of a window
+ */
+static HMENU get_win_sys_menu( HWND hwnd )
+{
+    HMENU ret = 0;
+    WND *win = get_win_ptr( hwnd );
+    if (win && win != WND_OTHER_PROCESS && win != WND_DESKTOP)
+    {
+        ret = win->hSysMenu;
+        release_win_ptr( win );
+    }
+    return ret;
+}
+
 static POPUPMENU *find_menu_item( HMENU handle, UINT id, UINT flags, UINT *pos )
 {
     UINT fallback_pos = ~0u, i;
@@ -346,6 +363,48 @@ static BOOL is_win_menu_disallowed( HWND hwnd )
     return (get_window_long(hwnd, GWL_STYLE) & (WS_CHILD | WS_POPUP)) == WS_CHILD;
 }
 
+/***********************************************************************
+ *           find_submenu
+ *
+ * Find a Sub menu. Return the position of the submenu, and modifies
+ * *hmenu in case it is found in another sub-menu.
+ * If the submenu cannot be found, NO_SELECTED_ITEM is returned.
+ */
+static UINT find_submenu( HMENU *handle_ptr, HMENU target )
+{
+    POPUPMENU *menu;
+    MENUITEM *item;
+    UINT i;
+
+    if (*handle_ptr == (HMENU)0xffff || !(menu = grab_menu_ptr( *handle_ptr )))
+        return NO_SELECTED_ITEM;
+
+    item = menu->items;
+    for (i = 0; i < menu->nItems; i++, item++)
+    {
+        if(!(item->fType & MF_POPUP)) continue;
+        if (item->hSubMenu == target)
+        {
+            release_menu_ptr( menu );
+            return i;
+        }
+        else
+        {
+            HMENU hsubmenu = item->hSubMenu;
+            UINT pos = find_submenu( &hsubmenu, target );
+            if (pos != NO_SELECTED_ITEM)
+            {
+                *handle_ptr = hsubmenu;
+                release_menu_ptr( menu );
+                return pos;
+            }
+        }
+    }
+
+    release_menu_ptr( menu );
+    return NO_SELECTED_ITEM;
+}
+
 /* see GetMenu */
 HMENU get_menu( HWND hwnd )
 {
@@ -932,6 +991,25 @@ BOOL WINAPI NtUserSetMenuContextHelpId( HMENU handle, DWORD id )
     return TRUE;
 }
 
+/* see GetSubMenu */
+static HMENU get_sub_menu( HMENU handle, INT pos )
+{
+    POPUPMENU *menu;
+    HMENU submenu;
+    UINT i;
+
+    if (!(menu = find_menu_item( handle, pos, MF_BYPOSITION, &i )))
+        return 0;
+
+    if (menu->items[i].fType & MF_POPUP)
+        submenu = menu->items[i].hSubMenu;
+    else
+        submenu = 0;
+
+    release_menu_ptr(menu);
+    return submenu;
+}
+
 /**********************************************************************
  *           NtUserSetMenuDefaultItem    (win32u.@)
  */
@@ -979,3 +1057,204 @@ BOOL WINAPI NtUserSetMenuDefaultItem( HMENU handle, UINT item, UINT bypos )
     release_menu_ptr( menu );
     return ret;
 }
+
+/**********************************************************************
+ *           translate_accelerator
+ */
+static BOOL translate_accelerator( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
+                                   BYTE virt, WORD key, WORD cmd )
+{
+    INT mask = 0;
+    UINT msg = 0;
+
+    if (wparam != key) return FALSE;
+
+    if (NtUserGetKeyState( VK_CONTROL ) & 0x8000) mask |= FCONTROL;
+    if (NtUserGetKeyState( VK_MENU ) & 0x8000)    mask |= FALT;
+    if (NtUserGetKeyState( VK_SHIFT ) & 0x8000)   mask |= FSHIFT;
+
+    if (message == WM_CHAR || message == WM_SYSCHAR)
+    {
+        if (!(virt & FVIRTKEY) && (mask & FALT) == (virt & FALT))
+        {
+            TRACE_(accel)( "found accel for WM_CHAR: ('%c')\n", LOWORD(wparam) & 0xff );
+            goto found;
+        }
+    }
+    else
+    {
+        if (virt & FVIRTKEY)
+        {
+            TRACE_(accel)( "found accel for virt_key %04lx (scan %04x)\n",
+                           wparam, 0xff & HIWORD(lparam) );
+
+            if (mask == (virt & (FSHIFT | FCONTROL | FALT))) goto found;
+            TRACE_(accel)( ", but incorrect SHIFT/CTRL/ALT-state\n" );
+        }
+        else
+        {
+            if (!(lparam & 0x01000000))  /* no special_key */
+            {
+                if ((virt & FALT) && (lparam & 0x20000000)) /* ALT pressed */
+                {
+                    TRACE_(accel)( "found accel for Alt-%c\n", LOWORD(wparam) & 0xff );
+                    goto found;
+                }
+            }
+        }
+    }
+    return FALSE;
+
+found:
+    if (message == WM_KEYUP || message == WM_SYSKEYUP)
+        msg = 1;
+    else
+    {
+        HMENU menu_handle, submenu, sys_menu;
+        UINT sys_stat = ~0u, stat = ~0u, pos;
+        POPUPMENU *menu;
+
+        menu_handle = (get_window_long( hwnd, GWL_STYLE ) & WS_CHILD) ? 0 : get_menu(hwnd);
+        sys_menu = get_win_sys_menu( hwnd );
+
+        /* find menu item and ask application to initialize it */
+        /* 1. in the system menu */
+        if ((menu = find_menu_item( sys_menu, cmd, MF_BYCOMMAND, NULL )))
+        {
+            submenu = menu->obj.handle;
+            release_menu_ptr( menu );
+
+            if (get_capture())
+                msg = 2;
+            if (!is_window_enabled( hwnd ))
+                msg = 3;
+            else
+            {
+                send_message( hwnd, WM_INITMENU, (WPARAM)sys_menu, 0 );
+                if (submenu != sys_menu)
+                {
+                    pos = find_submenu( &sys_menu, submenu );
+                    TRACE_(accel)( "sys_menu = %p, submenu = %p, pos = %d\n",
+                                   sys_menu, submenu, pos );
+                    send_message( hwnd, WM_INITMENUPOPUP, (WPARAM)submenu, MAKELPARAM(pos, TRUE) );
+                }
+                sys_stat = get_menu_state( get_sub_menu( sys_menu, 0 ), cmd, MF_BYCOMMAND );
+            }
+        }
+        else /* 2. in the window's menu */
+        {
+            if ((menu = find_menu_item( menu_handle, cmd, MF_BYCOMMAND, NULL )))
+            {
+                submenu = menu->obj.handle;
+                release_menu_ptr( menu );
+
+                if (get_capture())
+                    msg = 2;
+                if (!is_window_enabled( hwnd ))
+                    msg = 3;
+                else
+                {
+                    send_message( hwnd, WM_INITMENU, (WPARAM)menu_handle, 0 );
+                    if(submenu != menu_handle)
+                    {
+                        pos = find_submenu( &menu_handle, submenu );
+                        TRACE_(accel)( "menu_handle = %p, submenu = %p, pos = %d\n",
+                                       menu_handle, submenu, pos );
+                        send_message( hwnd, WM_INITMENUPOPUP, (WPARAM)submenu,
+                                      MAKELPARAM(pos, FALSE) );
+                    }
+                    stat = get_menu_state( menu_handle, cmd, MF_BYCOMMAND );
+                }
+            }
+        }
+
+        if (msg == 0)
+        {
+            if (sys_stat != ~0u)
+            {
+                if (sys_stat & (MF_DISABLED|MF_GRAYED))
+                    msg = 4;
+                else
+                    msg = WM_SYSCOMMAND;
+            }
+            else
+            {
+                if (stat != ~0u)
+                {
+                    if (is_iconic( hwnd ))
+                        msg = 5;
+                    else
+                    {
+                        if (stat & (MF_DISABLED|MF_GRAYED))
+                            msg = 6;
+                        else
+                            msg = WM_COMMAND;
+                    }
+                }
+                else
+                    msg = WM_COMMAND;
+            }
+        }
+    }
+
+    if (msg == WM_COMMAND)
+    {
+        TRACE_(accel)( ", sending WM_COMMAND, wparam=%0x\n", 0x10000 | cmd );
+        send_message( hwnd, msg, 0x10000 | cmd, 0 );
+    }
+    else if (msg == WM_SYSCOMMAND)
+    {
+        TRACE_(accel)( ", sending WM_SYSCOMMAND, wparam=%0x\n", cmd );
+        send_message( hwnd, msg, cmd, 0x00010000 );
+    }
+    else
+    {
+        /*  some reasons for NOT sending the WM_{SYS}COMMAND message:
+         *   #0: unknown (please report!)
+         *   #1: for WM_KEYUP,WM_SYSKEYUP
+         *   #2: mouse is captured
+         *   #3: window is disabled
+         *   #4: it's a disabled system menu option
+         *   #5: it's a menu option, but window is iconic
+         *   #6: it's a menu option, but disabled
+         */
+        TRACE_(accel)( ", but won't send WM_{SYS}COMMAND, reason is #%d\n", msg );
+        if (!msg) ERR_(accel)( " unknown reason\n" );
+    }
+    return TRUE;
+}
+
+/**********************************************************************
+ *           NtUserTranslateAccelerator     (win32u.@)
+ */
+INT WINAPI NtUserTranslateAccelerator( HWND hwnd, HACCEL accel, MSG *msg )
+{
+    ACCEL data[32], *ptr = data;
+    int i, count;
+
+    if (!hwnd) return 0;
+
+    if (msg->message != WM_KEYDOWN &&
+        msg->message != WM_SYSKEYDOWN &&
+        msg->message != WM_CHAR &&
+        msg->message != WM_SYSCHAR)
+        return 0;
+
+    TRACE_(accel)("accel %p, hwnd %p, msg->hwnd %p, msg->message %04x, wParam %08lx, lParam %08lx\n",
+                  accel,hwnd,msg->hwnd,msg->message,msg->wParam,msg->lParam);
+
+    if (!(count = NtUserCopyAcceleratorTable( accel, NULL, 0 ))) return 0;
+    if (count > ARRAY_SIZE( data ))
+    {
+        if (!(ptr = malloc( count * sizeof(*ptr) ))) return 0;
+    }
+    count = NtUserCopyAcceleratorTable( accel, ptr, count );
+    for (i = 0; i < count; i++)
+    {
+        if (translate_accelerator( hwnd, msg->message, msg->wParam, msg->lParam,
+                                   ptr[i].fVirt, ptr[i].key, ptr[i].cmd))
+            break;
+    }
+    if (ptr != data) free( ptr );
+    return (i < count);
+}
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index 07da23f633a..483b3d52289 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -1281,7 +1281,7 @@
 @ stub NtUserTrackPopupMenuEx
 @ stub NtUserTransformPoint
 @ stub NtUserTransformRect
-@ stub NtUserTranslateAccelerator
+@ stdcall NtUserTranslateAccelerator(long long ptr)
 @ stdcall NtUserTranslateMessage(ptr long)
 @ stub NtUserUndelegateInput
 @ stdcall -syscall NtUserUnhookWinEvent(long)
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h
index 537eec38a34..5a0787afca7 100644
--- a/dlls/win32u/win32u_private.h
+++ b/dlls/win32u/win32u_private.h
@@ -296,6 +296,7 @@ struct unix_funcs
     INT      (WINAPI *pNtUserToUnicodeEx)( UINT virt, UINT scan, const BYTE *state,
                                            WCHAR *str, int size, UINT flags, HKL layout );
     BOOL     (WINAPI *pNtUserTrackMouseEvent)( TRACKMOUSEEVENT *info );
+    INT      (WINAPI *pNtUserTranslateAccelerator)( HWND hwnd, HACCEL accel, MSG *msg );
     BOOL     (WINAPI *pNtUserTranslateMessage)( const MSG *msg, UINT flags );
     BOOL     (WINAPI *pNtUserUnregisterClass)( UNICODE_STRING *name, HINSTANCE instance,
                                                struct client_menu_name *client_menu_name );
diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c
index 05107352dfa..9a87bccbb7a 100644
--- a/dlls/win32u/wrappers.c
+++ b/dlls/win32u/wrappers.c
@@ -1258,6 +1258,12 @@ BOOL WINAPI NtUserTrackMouseEvent( TRACKMOUSEEVENT *info )
     return unix_funcs->pNtUserTrackMouseEvent( info );
 }
 
+INT WINAPI NtUserTranslateAccelerator( HWND hwnd, HACCEL accel, MSG *msg )
+{
+    if (!unix_funcs) return 0;
+    return unix_funcs->pNtUserTranslateAccelerator( hwnd, accel, msg );
+}
+
 BOOL WINAPI NtUserTranslateMessage( const MSG *msg, UINT flags )
 {
     if (!unix_funcs) return 0;
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/18



More information about the wine-devel mailing list