Make Alt+[national key] menu shortcuts work

Dmitry Timoshkov dmitry at baikal.ru
Wed Nov 19 02:56:28 CST 2003


Hello,

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
default code patch, which expects unicode characters.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    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	Wed Nov 19 16:14:43 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	Wed Nov 19 16:04:24 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	Wed Nov 19 16:17:40 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,16 +572,19 @@ static LRESULT DEFWND_DefWinProc( HWND h
         break;
 
     case WM_SYSCHAR:
+    {
+        SHORT vkey = VkKeyScanW(wParam);
+
 	iMenuSysKey = 0;
-	if (wParam == VK_RETURN && IsIconic(hwnd))
+        if (vkey == VK_RETURN && 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 (vkey == VK_TAB || vkey == VK_ESCAPE) break;
+            if (vkey == VK_SPACE && (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD))
                 SendMessageW( GetParent(hwnd), msg, wParam, lParam );
 	    else
                 SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
@@ -589,6 +592,7 @@ static LRESULT DEFWND_DefWinProc( HWND h
 	else /* check for Ctrl-Esc */
             if (wParam != VK_ESCAPE) MessageBeep(0);
 	break;
+    }
 
     case WM_SHOWWINDOW:
         {
@@ -867,6 +871,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	Wed Nov 19 16:04:24 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:






More information about the wine-patches mailing list