Alexandre Julliard : user32: Add support for right-to-left menus.

Alexandre Julliard julliard at winehq.org
Wed Sep 22 14:47:55 CDT 2010


Module: wine
Branch: master
Commit: 5c6a1f776a7a6a3c723721cdd46462e7bfcb3295
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5c6a1f776a7a6a3c723721cdd46462e7bfcb3295

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Sep 22 20:31:52 2010 +0200

user32: Add support for right-to-left menus.

---

 dlls/user32/menu.c      |   27 ++++++++++++++++++++++-----
 dlls/user32/nonclient.c |    3 ++-
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index e4dc607..4d2edf8 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -727,7 +727,8 @@ static MENUITEM *MENU_FindItemByCoords( const POPUPMENU *menu,
     RECT rect;
 
     if (!GetWindowRect(menu->hWnd, &rect)) return NULL;
-    pt.x -= rect.left;
+    if (GetWindowLongW( menu->hWnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) pt.x = rect.right - 1 - pt.x;
+    else pt.x -= rect.left;
     pt.y -= rect.top;
     item = menu->items;
     for (i = 0; i < menu->nItems; i++, item++)
@@ -1834,6 +1835,7 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
     POINT pt;
     HMONITOR monitor;
     MONITORINFO info;
+    DWORD ex_style = 0;
 
     TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
           hwndOwner, hmenu, id, x, y, xanchor, yanchor);
@@ -1863,6 +1865,12 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
     info.cbSize = sizeof(info);
     GetMonitorInfoW( monitor, &info );
 
+    if (flags & TPM_LAYOUTRTL)
+    {
+        ex_style = WS_EX_LAYOUTRTL;
+        flags ^= TPM_RIGHTALIGN;
+    }
+
     if( flags & TPM_RIGHTALIGN ) x -= width;
     if( flags & TPM_CENTERALIGN ) x -= width / 2;
 
@@ -1890,7 +1898,7 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
     if( y < info.rcWork.top ) y = info.rcWork.top;
 
     /* NOTE: In Windows, top menu popup is not owned. */
-    menu->hWnd = CreateWindowExW( 0, (LPCWSTR)POPUPMENU_CLASS_ATOM, NULL,
+    menu->hWnd = CreateWindowExW( ex_style, (LPCWSTR)POPUPMENU_CLASS_ATOM, NULL,
                                 WS_POPUP, x, y, width, height,
                                 hwndOwner, 0, (HINSTANCE)GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
                                 (LPVOID)hmenu );
@@ -2339,6 +2347,7 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
                               GetClassLongW( menu->hWnd, GCL_STYLE));
 
 	NC_GetSysPopupPos( menu->hWnd, &rect );
+	if (wFlags & TPM_LAYOUTRTL) rect.left = rect.right;
 	rect.top = rect.bottom;
 	rect.right = GetSystemMetrics(SM_CXSIZE);
         rect.bottom = GetSystemMetrics(SM_CYSIZE);
@@ -2354,7 +2363,10 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
 
 	    /* The first item in the popup menu has to be at the
 	       same y position as the focused menu item */
-	    rect.left += rc.right - GetSystemMetrics(SM_CXBORDER);
+            if (wFlags & TPM_LAYOUTRTL)
+                rect.left += GetSystemMetrics(SM_CXBORDER);
+	    else
+                rect.left += rc.right - GetSystemMetrics(SM_CXBORDER);
 	    rect.top += rc.top - MENU_TOP_MARGIN;
 	    rect.right = rc.left - rc.right + GetSystemMetrics(SM_CXBORDER);
 	    rect.bottom = rc.top - rc.bottom - MENU_TOP_MARGIN
@@ -2362,14 +2374,17 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
 	}
 	else
 	{
-	    rect.left += item->rect.left;
+            if (wFlags & TPM_LAYOUTRTL)
+                rect.left = rect.right - item->rect.left;
+	    else
+                rect.left += item->rect.left;
 	    rect.top += item->rect.bottom;
 	    rect.right = item->rect.right - item->rect.left;
 	    rect.bottom = item->rect.bottom - item->rect.top;
 	}
     }
 
-    MENU_ShowPopup( hwndOwner, item->hSubMenu, menu->FocusedItem, 0,
+    MENU_ShowPopup( hwndOwner, item->hSubMenu, menu->FocusedItem, wFlags,
 		    rect.left, rect.top, rect.right, rect.bottom );
     if (selectFirst)
         MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT );
@@ -3319,6 +3334,7 @@ void MENU_TrackMouseMenuBar( HWND hWnd, INT ht, POINT pt )
 
     TRACE("wnd=%p ht=0x%04x %s\n", hWnd, ht, wine_dbgstr_point( &pt));
 
+    if (GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) wFlags |= TPM_LAYOUTRTL;
     if (IsMenu(hMenu))
     {
 	MENU_InitTracking( hWnd, hMenu, FALSE, wFlags );
@@ -3356,6 +3372,7 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar)
         uItem = 0;
         wParam |= HTSYSMENU; /* prevent item lookup */
     }
+    if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) wFlags |= TPM_LAYOUTRTL;
 
     if (!IsMenu( hTrackMenu )) return;
 
diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c
index 051041c..f385445 100644
--- a/dlls/user32/nonclient.c
+++ b/dlls/user32/nonclient.c
@@ -1185,9 +1185,10 @@ void NC_GetSysPopupPos( HWND hwnd, RECT* rect )
         DWORD style = GetWindowLongW( hwnd, GWL_STYLE );
         DWORD ex_style = GetWindowLongW( hwnd, GWL_EXSTYLE );
 
-        NC_GetInsideRect( hwnd, COORDS_SCREEN, rect, style, ex_style );
+        NC_GetInsideRect( hwnd, COORDS_CLIENT, rect, style, ex_style );
         rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
         rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
+        MapWindowPoints( hwnd, 0, (POINT *)rect, 2 );
     }
 }
 




More information about the wine-cvs mailing list