menu: drawing fixes split #2

Rein Klazes wijn at wanadoo.nl
Sun Feb 19 07:39:32 CST 2006


Hi,

Needs patch split #1 to be applied first.


Changelog:
dlls/user	: menu.c
- Move sending WM_MEASUREITEM message for HBMMENU_CALLBACK bitmaps to
MENU_GetBitmapItemSize();
- Save the received bitmap size in the menu item structure as it will
need to be sent in the WM_DRAWITEM message;
-  Move sending WM_DRAWITEM message for HBMMENU_CALLBACK bitmaps to
MENU_DrawBitmapItem();
- This also means that HBMMENU_CALLBACK bitmaps are now supported in
menu bars.

Rein.
-------------- next part --------------
--- mywine/dlls/user/menu-1.c	2006-02-19 13:56:22.000000000 +0100
+++ mywine/dlls/user/menu.c	2006-02-19 14:01:03.000000000 +0100
@@ -85,6 +85,8 @@ typedef struct {
     /* ----------- Wine stuff ----------- */
     RECT      rect;		/* Item area (relative to menu window) */
     UINT      xTab;		/* X position of text after Tab */
+    SIZE   bmpsize;             /* size needed for the HBMMENU_CALLBACK
+                                 * bitmap */ 
 } MENUITEM;
 
 /* Popup menu structure */
@@ -771,19 +773,36 @@ static UINT MENU_FindItemByKey( HWND hwn
  *
  * Get the size of a bitmap item.
  */
-static void MENU_GetBitmapItemSize( HBITMAP bmp, DWORD data, SIZE *size )
+static void MENU_GetBitmapItemSize( MENUITEM *lpitem, SIZE *size,
+                                    HWND hwndOwner)
 {
     BITMAP bm;
+    HBITMAP bmp = lpitem->hbmpItem;
 
     size->cx = size->cy = 0;
 
     /* check if there is a magic menu item associated with this item */
-    switch( (INT_PTR)bmp )
+    switch( (INT_PTR) bmp )
     {
+    case (INT_PTR)HBMMENU_CALLBACK:
+        {
+            MEASUREITEMSTRUCT measItem;
+            measItem.CtlType = ODT_MENU;
+            measItem.CtlID = 0;
+            measItem.itemID = lpitem->wID;
+            measItem.itemWidth = lpitem->rect.right - lpitem->rect.left;
+            measItem.itemHeight = lpitem->rect.bottom - lpitem->rect.top;
+            measItem.itemData = lpitem->dwItemData;
+            SendMessageW( hwndOwner, WM_MEASUREITEM, lpitem->wID, (LPARAM)&measItem);
+            size->cx = measItem.itemWidth;
+            size->cy = measItem.itemHeight;
+            return;
+        }
+        break;
     case (INT_PTR)HBMMENU_SYSTEM:
-        if (data)
+        if (lpitem->dwItemData)
         {
-            bmp = (HBITMAP)data;
+            bmp = (HBITMAP)lpitem->dwItemData;
             break;
         }
         /* fall through */
@@ -795,7 +814,6 @@ static void MENU_GetBitmapItemSize( HBIT
         size->cx = GetSystemMetrics( SM_CYMENU ) - 4;
         size->cy = size->cx;
         return;
-    case (INT_PTR)HBMMENU_CALLBACK:
     case (INT_PTR)HBMMENU_POPUP_CLOSE:
     case (INT_PTR)HBMMENU_POPUP_RESTORE:
     case (INT_PTR)HBMMENU_POPUP_MAXIMIZE:
@@ -815,7 +833,8 @@ static void MENU_GetBitmapItemSize( HBIT
  *
  * Draw a bitmap item.
  */
-static void MENU_DrawBitmapItem( HDC hdc, MENUITEM *lpitem, const RECT *rect, BOOL menuBar)
+static void MENU_DrawBitmapItem( HDC hdc, MENUITEM *lpitem, const RECT *rect,
+                    HMENU hmenu, HWND hwndOwner, UINT odaction, BOOL menuBar)
 {
     BITMAP bm;
     DWORD rop;
@@ -870,6 +889,25 @@ static void MENU_DrawBitmapItem( HDC hdc
             flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE;
             break;
         case (INT_PTR)HBMMENU_CALLBACK:
+            {
+                DRAWITEMSTRUCT drawItem;
+                drawItem.CtlType = ODT_MENU;
+                drawItem.CtlID = 0;
+                drawItem.itemID = lpitem->wID;
+                drawItem.itemAction = odaction;
+                drawItem.itemState = (lpitem->fState & MF_CHECKED)?ODS_CHECKED:0;
+                drawItem.itemState |= (lpitem->fState & MF_DEFAULT)?ODS_DEFAULT:0;
+                drawItem.itemState |= (lpitem->fState & MF_DISABLED)?ODS_DISABLED:0;
+                drawItem.itemState |= (lpitem->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0;
+                drawItem.itemState |= (lpitem->fState & MF_HILITE)?ODS_SELECTED:0;
+                drawItem.hwndItem = (HWND)hmenu;
+                drawItem.hDC = hdc;
+                drawItem.itemData = lpitem->dwItemData;
+                drawItem.rcItem = *rect;
+                SendMessageW( hwndOwner, WM_DRAWITEM, 0, (LPARAM)&drawItem);
+                return;
+            }
+            break;
         case (INT_PTR)HBMMENU_POPUP_CLOSE:
         case (INT_PTR)HBMMENU_POPUP_RESTORE:
         case (INT_PTR)HBMMENU_POPUP_MAXIMIZE:
@@ -964,34 +1002,18 @@ static void MENU_CalcItemSize( HDC hdc, 
 	return;
     }
 
-    if (!menuBar)
-    {
-	if (lpitem->hbmpItem) 
-	{
-	    if (lpitem->hbmpItem == HBMMENU_CALLBACK)
-	    {
-		MEASUREITEMSTRUCT measItem;
-		measItem.CtlType = ODT_MENU;
-		measItem.CtlID = 0;
-		measItem.itemID = lpitem->wID;
-		measItem.itemWidth = lpitem->rect.right - lpitem->rect.left;
-		measItem.itemHeight = lpitem->rect.bottom - lpitem->rect.top;
-		measItem.itemData = lpitem->dwItemData;
-		
-		SendMessageW( hwndOwner, WM_MEASUREITEM, lpitem->wID, (LPARAM)&measItem);
-	    
-		/* Keep the size of the bitmap in callback mode to be able to draw it correctly */
-		lppop->maxBmpSize.cx = max(lppop->maxBmpSize.cx, measItem.itemWidth - (lpitem->rect.right - lpitem->rect.left));
-		lppop->maxBmpSize.cy = max(lppop->maxBmpSize.cy, measItem.itemHeight - (lpitem->rect.bottom - lpitem->rect.top));
-		lpitem->rect.right = lpitem->rect.left + measItem.itemWidth;
-	    } else {
-		SIZE size;
-		MENU_GetBitmapItemSize(lpitem->hbmpItem, lpitem->dwItemData, &size);
-		lppop->maxBmpSize.cx = max(lppop->maxBmpSize.cx, size.cx);
-		lppop->maxBmpSize.cy = max(lppop->maxBmpSize.cy, size.cy);
-		lpitem->rect.right  += size.cx;
-		lpitem->rect.bottom += size.cy;
-	    }
+    if (!menuBar) {
+        if (lpitem->hbmpItem) {
+            SIZE size;
+            
+            MENU_GetBitmapItemSize(lpitem, &size, hwndOwner);
+            /* Keep the size of the bitmap in callback mode to be able
+             * to draw it correctly */
+            lpitem->bmpsize = size;
+            lppop->maxBmpSize.cx = max( lppop->maxBmpSize.cx, size.cx);
+            lppop->maxBmpSize.cy = max( lppop->maxBmpSize.cy, size.cy);
+            lpitem->rect.right  += size.cx;
+            lpitem->rect.bottom += size.cy;
 	    if (lppop->dwStyle & MNS_CHECKORBMP) 
 		lpitem->rect.right += check_bitmap_width;
 	    else
@@ -1000,11 +1022,11 @@ static void MENU_CalcItemSize( HDC hdc, 
 	    lpitem->rect.right += 2 * check_bitmap_width;
 	if (lpitem->fType & MF_POPUP)
 	    lpitem->rect.right += arrow_bitmap_width;
-    } else if (lpitem->hbmpItem)
-    {
+    } else if (lpitem->hbmpItem) { /* menuBar */
         SIZE size;
 
-        MENU_GetBitmapItemSize( (HBITMAP) lpitem->hbmpItem, lpitem->dwItemData, &size );
+        MENU_GetBitmapItemSize( lpitem, &size, hwndOwner );
+        lpitem->bmpsize = size;
         lpitem->rect.right  += size.cx;
         lpitem->rect.bottom += size.cy;
         /* Leave space for the sunken border */
@@ -1294,6 +1316,8 @@ static void MENU_DrawMenuItem( HWND hwnd
     BOOL flat_menu = FALSE;
     int bkgnd;
     UINT arrow_bitmap_width = 0, arrow_bitmap_height = 0;
+    POPUPMENU *menu = MENU_GetMenu(hmenu);
+    RECT bmprc;
 
     debug_print_menuitem("MENU_DrawMenuItem: ", lpitem, "");
 
@@ -1452,6 +1476,28 @@ static void MENU_DrawMenuItem( HWND hwnd
 	LineTo( hdc, rect.right, (rect.top + rect.bottom)/2 );
 */
 
+    if (lpitem->hbmpItem) {
+        /* calculate the bitmap rectangle in coordinates relative
+         * to the item rectangle */
+        if( menuBar) {
+            if( lpitem->hbmpItem == HBMMENU_CALLBACK)
+                bmprc.left = 3;
+            else 
+                bmprc.left = lpitem->text ? menucharsize.cx : 0;          
+        } else {
+            bmprc.left = 4;
+            if( !(menu->dwStyle & MNS_NOCHECK))
+                bmprc.left += GetSystemMetrics( SM_CXMENUCHECK); 
+        }
+        bmprc.right =  bmprc.left + lpitem->bmpsize.cx;
+        if( menuBar && !(lpitem->hbmpItem == HBMMENU_CALLBACK))
+            bmprc.top = 0;
+        else
+            bmprc.top = (lpitem->rect.bottom - lpitem->rect.top -
+                    lpitem->bmpsize.cy) / 2; 
+        bmprc.bottom =  bmprc.top + lpitem->bmpsize.cy;
+    }
+
     if (!menuBar)
     {
         HBITMAP bm;
@@ -1500,34 +1546,12 @@ static void MENU_DrawMenuItem( HWND hwnd
         }
         if (lpitem->hbmpItem)
         {
-            HBITMAP hbm = lpitem->hbmpItem;
-
-            if (hbm == HBMMENU_CALLBACK)
-            {
-                DRAWITEMSTRUCT drawItem;
-                POINT origorg;
-                drawItem.CtlType = ODT_MENU;
-                drawItem.CtlID = 0;
-                drawItem.itemID = lpitem->wID;
-                drawItem.itemAction = odaction;
-                drawItem.itemState = (lpitem->fState & MF_CHECKED)?ODS_CHECKED:0;
-                drawItem.itemState |= (lpitem->fState & MF_DEFAULT)?ODS_DEFAULT:0;
-                drawItem.itemState |= (lpitem->fState & MF_DISABLED)?ODS_DISABLED:0;
-                drawItem.itemState |= (lpitem->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0;
-                drawItem.itemState |= (lpitem->fState & MF_HILITE)?ODS_SELECTED:0;
-                drawItem.hwndItem = (HWND)hmenu;
-                drawItem.hDC = hdc;
-                drawItem.rcItem = lpitem->rect;
-                drawItem.itemData = lpitem->dwItemData;
-                /* some applications make this assumption on the DC's origin */
-                SetViewportOrgEx( hdc, lpitem->rect.left, lpitem->rect.top, &origorg);
-                OffsetRect( &drawItem.rcItem, - lpitem->rect.left, - lpitem->rect.top);
-                SendMessageW( hwndOwner, WM_DRAWITEM, 0, (LPARAM)&drawItem);
-                SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
-
-            } else {
-                MENU_DrawBitmapItem(hdc, lpitem, &rect, FALSE);
-            }
+            POINT origorg;
+            /* some applications make this assumption on the DC's origin */
+            SetViewportOrgEx( hdc, lpitem->rect.left, lpitem->rect.top, &origorg);
+            MENU_DrawBitmapItem(hdc, lpitem, &bmprc, hmenu, hwndOwner,
+                    odaction, FALSE);
+            SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
         }
 	/* Draw the popup-menu arrow */
         if (lpitem->fType & MF_POPUP)
@@ -1539,7 +1563,12 @@ static void MENU_DrawMenuItem( HWND hwnd
     }
     else if( lpitem->hbmpItem)
     {   /* Draw the bitmap */
-	MENU_DrawBitmapItem( hdc, lpitem, &rect, menuBar);
+        POINT origorg;
+        
+        SetViewportOrgEx( hdc, lpitem->rect.left, lpitem->rect.top, &origorg);
+        MENU_DrawBitmapItem( hdc, lpitem, &bmprc, hmenu, hwndOwner,
+                odaction, menuBar);
+        SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
     }
     /* process text if present */
     if (lpitem->text)


More information about the wine-patches mailing list