Hello, This patch changes DefWindowProc(WM_SYSCHAR) handler so, that it uses character codes and not VK_* codes for comparisons, since WM_SYSCHAR receives a character, not a virtual key. Otherwise the patch is the same. WM_SYSCOMMAND/SC_KEYMENU accepts a character code, not a virtual key code. Also, DefWindowProcA(WM_SYSCHAR) should convert a character code to unicode before passing it to the default code path, which expects a unicode characters. Changelog: Dmitry Timoshkov <dmitry@xxxxxxxxxxxxxxx> Make Alt+[national key] menu shortcuts work. diff -u cvs/hq/wine/controls/menu.c wine/controls/menu.c --- cvs/hq/wine/controls/menu.c Wed Nov 19 15:06:42 2003 +++ wine/controls/menu.c Tue Nov 25 12:19:35 2003 @@ -664,7 +664,7 @@ static MENUITEM *MENU_FindItemByCoords( * Return item id, -1 if none, -2 if we should close the menu. */ static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, - UINT key, BOOL forceMenuChar ) + WCHAR key, BOOL forceMenuChar ) { TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char)key, key, hmenu ); @@ -3000,12 +3000,14 @@ void MENU_TrackMouseMenuBar( HWND hWnd, * * Menu-bar tracking upon a keyboard event. Called from NC_HandleSysCommand(). */ -void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, INT vkey) +void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar) { UINT uItem = NO_SELECTED_ITEM; HMENU hTrackMenu; UINT wFlags = TPM_ENTERIDLEEX | TPM_LEFTALIGN | TPM_LEFTBUTTON; + TRACE("hwnd %p wParam 0x%04x wChar 0x%04x\n", hwnd, wParam, wChar); + /* find window that has a menu */ while (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) @@ -3014,7 +3016,7 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UI /* check if we have to track a system menu */ hTrackMenu = GetMenu( hwnd ); - if (!hTrackMenu || IsIconic(hwnd) || vkey == VK_SPACE ) + if (!hTrackMenu || IsIconic(hwnd) || wChar == ' ' ) { if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_SYSMENU)) return; if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_MANAGED) return; @@ -3027,9 +3029,9 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UI MENU_InitTracking( hwnd, hTrackMenu, FALSE, wFlags ); - if( vkey && vkey != VK_SPACE ) + if( wChar && wChar != ' ' ) { - uItem = MENU_FindItemByKey( hwnd, hTrackMenu, vkey, (wParam & HTSYSMENU) ); + uItem = MENU_FindItemByKey( hwnd, hTrackMenu, wChar, (wParam & HTSYSMENU) ); if( uItem >= (UINT)(-2) ) { if( uItem == (UINT)(-1) ) MessageBeep(0); @@ -3043,7 +3045,7 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UI if( uItem == NO_SELECTED_ITEM ) MENU_MoveSelection( hwnd, hTrackMenu, ITEM_NEXT ); - else if( vkey ) + else if( wChar ) PostMessageW( hwnd, WM_KEYDOWN, VK_DOWN, 0L ); MENU_TrackMenu( hTrackMenu, wFlags, 0, 0, hwnd, NULL ); diff -u cvs/hq/wine/dlls/user/controls.h wine/dlls/user/controls.h --- cvs/hq/wine/dlls/user/controls.h Wed Nov 19 15:06:49 2003 +++ wine/dlls/user/controls.h Tue Nov 25 12:19:35 2003 @@ -59,7 +59,7 @@ extern HMENU MENU_GetSysMenu(HWND hWndOw extern UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth, INT orgX, INT orgY ); extern void MENU_TrackMouseMenuBar( HWND hwnd, INT ht, POINT pt ); -extern void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, INT vkey ); +extern void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar ); extern UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd, BOOL suppress_draw ); extern UINT MENU_FindSubMenu( HMENU *hmenu, HMENU hSubTarget ); diff -u cvs/hq/wine/windows/defwnd.c wine/windows/defwnd.c --- cvs/hq/wine/windows/defwnd.c Mon Nov 17 14:11:50 2003 +++ wine/windows/defwnd.c Tue Nov 25 12:23:44 2003 @@ -559,7 +559,7 @@ static LRESULT DEFWND_DefWinProc( HWND h iF10Key = 1; else if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) & 0x8000)) - SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, VK_SPACE ); + SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, ' ' ); break; case WM_KEYUP: @@ -572,23 +572,25 @@ static LRESULT DEFWND_DefWinProc( HWND h break; case WM_SYSCHAR: + { iMenuSysKey = 0; - if (wParam == VK_RETURN && IsIconic(hwnd)) + if (wParam == '\r' && IsIconic(hwnd)) { PostMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L ); break; } if ((HIWORD(lParam) & KEYDATA_ALT) && wParam) { - if (wParam == VK_TAB || wParam == VK_ESCAPE) break; - if (wParam == VK_SPACE && (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)) + if (wParam == '\t' || wParam == '\x1b') break; + if (wParam == ' ' && (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)) SendMessageW( GetParent(hwnd), msg, wParam, lParam ); else SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, wParam ); } else /* check for Ctrl-Esc */ - if (wParam != VK_ESCAPE) MessageBeep(0); + if (wParam != '\x1b') MessageBeep(0); break; + } case WM_SHOWWINDOW: { @@ -867,6 +869,14 @@ LRESULT WINAPI DefWindowProcA( HWND hwnd result = 0; break; + case WM_SYSCHAR: + { + BYTE ch = LOWORD(wParam); + WCHAR wch; + MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1); + wParam = MAKEWPARAM( wch, HIWORD(wParam) ); + } + /* fall through */ default: result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam ); break; diff -u cvs/hq/wine/windows/nonclient.c wine/windows/nonclient.c --- cvs/hq/wine/windows/nonclient.c Thu Sep 18 10:44:38 2003 +++ wine/windows/nonclient.c Tue Nov 25 12:19:35 2003 @@ -2193,7 +2193,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WPA break; case SC_KEYMENU: - MENU_TrackKbdMenuBar( hwnd, wParam, LOWORD(lParam) ); + MENU_TrackKbdMenuBar( hwnd, wParam, (WCHAR)lParam ); break; case SC_TASKLIST: