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.
This commit is contained in:
parent
672a1e4e4e
commit
444a547135
143
dlls/user/menu.c
143
dlls/user/menu.c
|
@ -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,
|
||||||
*
|
*
|
||||||
* 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_SYSTEM:
|
case (INT_PTR)HBMMENU_CALLBACK:
|
||||||
if (data)
|
|
||||||
{
|
{
|
||||||
bmp = (HBITMAP)data;
|
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 (lpitem->dwItemData)
|
||||||
|
{
|
||||||
|
bmp = (HBITMAP)lpitem->dwItemData;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
@ -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 )
|
||||||
*
|
*
|
||||||
* 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
|
||||||
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,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!menuBar)
|
if (!menuBar) {
|
||||||
{
|
if (lpitem->hbmpItem) {
|
||||||
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;
|
SIZE size;
|
||||||
MENU_GetBitmapItemSize(lpitem->hbmpItem, lpitem->dwItemData, &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.cx = max( lppop->maxBmpSize.cx, size.cx);
|
||||||
lppop->maxBmpSize.cy = max( lppop->maxBmpSize.cy, size.cy);
|
lppop->maxBmpSize.cy = max( lppop->maxBmpSize.cy, size.cy);
|
||||||
lpitem->rect.right += size.cx;
|
lpitem->rect.right += size.cx;
|
||||||
lpitem->rect.bottom += size.cy;
|
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
if (lpitem->hbmpItem)
|
if (lpitem->hbmpItem)
|
||||||
{
|
{
|
||||||
HBITMAP hbm = lpitem->hbmpItem;
|
|
||||||
|
|
||||||
if (hbm == HBMMENU_CALLBACK)
|
|
||||||
{
|
|
||||||
DRAWITEMSTRUCT drawItem;
|
|
||||||
POINT origorg;
|
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 */
|
/* some applications make this assumption on the DC's origin */
|
||||||
SetViewportOrgEx( hdc, lpitem->rect.left, lpitem->rect.top, &origorg);
|
SetViewportOrgEx( hdc, lpitem->rect.left, lpitem->rect.top, &origorg);
|
||||||
OffsetRect( &drawItem.rcItem, - lpitem->rect.left, - lpitem->rect.top);
|
MENU_DrawBitmapItem(hdc, lpitem, &bmprc, hmenu, hwndOwner,
|
||||||
SendMessageW( hwndOwner, WM_DRAWITEM, 0, (LPARAM)&drawItem);
|
odaction, FALSE);
|
||||||
SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
|
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,
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue