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