Commit 444a5471 authored by Rein Klazes's avatar Rein Klazes Committed by Alexandre Julliard

user: Menu drawing fixes.

- 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.
parent 672a1e4e
...@@ -85,6 +85,8 @@ typedef struct { ...@@ -85,6 +85,8 @@ typedef struct {
/* ----------- Wine stuff ----------- */ /* ----------- Wine stuff ----------- */
RECT rect; /* Item area (relative to menu window) */ RECT rect; /* Item area (relative to menu window) */
UINT xTab; /* X position of text after Tab */ UINT xTab; /* X position of text after Tab */
SIZE bmpsize; /* size needed for the HBMMENU_CALLBACK
* bitmap */
} MENUITEM; } MENUITEM;
/* Popup menu structure */ /* Popup menu structure */
...@@ -771,19 +773,36 @@ static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, ...@@ -771,19 +773,36 @@ static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu,
* *
* Get the size of a bitmap item. * 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; BITMAP bm;
HBITMAP bmp = lpitem->hbmpItem;
size->cx = size->cy = 0; size->cx = size->cy = 0;
/* check if there is a magic menu item associated with this item */ /* 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: case (INT_PTR)HBMMENU_SYSTEM:
if (data) if (lpitem->dwItemData)
{ {
bmp = (HBITMAP)data; bmp = (HBITMAP)lpitem->dwItemData;
break; break;
} }
/* fall through */ /* fall through */
...@@ -795,7 +814,6 @@ static void MENU_GetBitmapItemSize( HBITMAP bmp, DWORD data, SIZE *size ) ...@@ -795,7 +814,6 @@ static void MENU_GetBitmapItemSize( HBITMAP bmp, DWORD data, SIZE *size )
size->cx = GetSystemMetrics( SM_CYMENU ) - 4; size->cx = GetSystemMetrics( SM_CYMENU ) - 4;
size->cy = size->cx; size->cy = size->cx;
return; return;
case (INT_PTR)HBMMENU_CALLBACK:
case (INT_PTR)HBMMENU_POPUP_CLOSE: case (INT_PTR)HBMMENU_POPUP_CLOSE:
case (INT_PTR)HBMMENU_POPUP_RESTORE: case (INT_PTR)HBMMENU_POPUP_RESTORE:
case (INT_PTR)HBMMENU_POPUP_MAXIMIZE: case (INT_PTR)HBMMENU_POPUP_MAXIMIZE:
...@@ -815,7 +833,8 @@ static void MENU_GetBitmapItemSize( HBITMAP bmp, DWORD data, SIZE *size ) ...@@ -815,7 +833,8 @@ static void MENU_GetBitmapItemSize( HBITMAP bmp, DWORD data, SIZE *size )
* *
* Draw a bitmap item. * 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; BITMAP bm;
DWORD rop; DWORD rop;
...@@ -870,6 +889,25 @@ static void MENU_DrawBitmapItem( HDC hdc, MENUITEM *lpitem, const RECT *rect, BO ...@@ -870,6 +889,25 @@ static void MENU_DrawBitmapItem( HDC hdc, MENUITEM *lpitem, const RECT *rect, BO
flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE; flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE;
break; break;
case (INT_PTR)HBMMENU_CALLBACK: 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_CLOSE:
case (INT_PTR)HBMMENU_POPUP_RESTORE: case (INT_PTR)HBMMENU_POPUP_RESTORE:
case (INT_PTR)HBMMENU_POPUP_MAXIMIZE: case (INT_PTR)HBMMENU_POPUP_MAXIMIZE:
...@@ -964,34 +1002,18 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner, ...@@ -964,34 +1002,18 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
return; return;
} }
if (!menuBar) if (!menuBar) {
{ if (lpitem->hbmpItem) {
if (lpitem->hbmpItem) SIZE size;
{
if (lpitem->hbmpItem == HBMMENU_CALLBACK) MENU_GetBitmapItemSize(lpitem, &size, hwndOwner);
{ /* Keep the size of the bitmap in callback mode to be able
MEASUREITEMSTRUCT measItem; * to draw it correctly */
measItem.CtlType = ODT_MENU; lpitem->bmpsize = size;
measItem.CtlID = 0; lppop->maxBmpSize.cx = max( lppop->maxBmpSize.cx, size.cx);
measItem.itemID = lpitem->wID; lppop->maxBmpSize.cy = max( lppop->maxBmpSize.cy, size.cy);
measItem.itemWidth = lpitem->rect.right - lpitem->rect.left; lpitem->rect.right += size.cx;
measItem.itemHeight = lpitem->rect.bottom - lpitem->rect.top; lpitem->rect.bottom += size.cy;
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 (lppop->dwStyle & MNS_CHECKORBMP) if (lppop->dwStyle & MNS_CHECKORBMP)
lpitem->rect.right += check_bitmap_width; lpitem->rect.right += check_bitmap_width;
else else
...@@ -1000,11 +1022,11 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner, ...@@ -1000,11 +1022,11 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
lpitem->rect.right += 2 * check_bitmap_width; lpitem->rect.right += 2 * check_bitmap_width;
if (lpitem->fType & MF_POPUP) if (lpitem->fType & MF_POPUP)
lpitem->rect.right += arrow_bitmap_width; lpitem->rect.right += arrow_bitmap_width;
} else if (lpitem->hbmpItem) } else if (lpitem->hbmpItem) { /* menuBar */
{
SIZE size; 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.right += size.cx;
lpitem->rect.bottom += size.cy; lpitem->rect.bottom += size.cy;
/* Leave space for the sunken border */ /* Leave space for the sunken border */
...@@ -1294,6 +1316,8 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc, ...@@ -1294,6 +1316,8 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
BOOL flat_menu = FALSE; BOOL flat_menu = FALSE;
int bkgnd; int bkgnd;
UINT arrow_bitmap_width = 0, arrow_bitmap_height = 0; UINT arrow_bitmap_width = 0, arrow_bitmap_height = 0;
POPUPMENU *menu = MENU_GetMenu(hmenu);
RECT bmprc;
debug_print_menuitem("MENU_DrawMenuItem: ", lpitem, ""); debug_print_menuitem("MENU_DrawMenuItem: ", lpitem, "");
...@@ -1452,6 +1476,28 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc, ...@@ -1452,6 +1476,28 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
LineTo( hdc, rect.right, (rect.top + rect.bottom)/2 ); 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) if (!menuBar)
{ {
HBITMAP bm; HBITMAP bm;
...@@ -1500,34 +1546,12 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc, ...@@ -1500,34 +1546,12 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
} }
if (lpitem->hbmpItem) if (lpitem->hbmpItem)
{ {
HBITMAP hbm = lpitem->hbmpItem; POINT origorg;
/* some applications make this assumption on the DC's origin */
if (hbm == HBMMENU_CALLBACK) SetViewportOrgEx( hdc, lpitem->rect.left, lpitem->rect.top, &origorg);
{ MENU_DrawBitmapItem(hdc, lpitem, &bmprc, hmenu, hwndOwner,
DRAWITEMSTRUCT drawItem; odaction, FALSE);
POINT origorg; SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
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);
}
} }
/* Draw the popup-menu arrow */ /* Draw the popup-menu arrow */
if (lpitem->fType & MF_POPUP) if (lpitem->fType & MF_POPUP)
...@@ -1539,7 +1563,12 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc, ...@@ -1539,7 +1563,12 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
} }
else if( lpitem->hbmpItem) else if( lpitem->hbmpItem)
{ /* Draw the bitmap */ { /* 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 */ /* process text if present */
if (lpitem->text) if (lpitem->text)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment