Fixed to display popup-menu arrow on owner-drawn popup menus.
Fixed positioning of submenus relative to parent menus.
This commit is contained in:
parent
8c8237b756
commit
130f0d88c1
176
controls/menu.c
176
controls/menu.c
|
@ -780,6 +780,13 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
|
|||
|
||||
if (lpitem->fType & MF_OWNERDRAW)
|
||||
{
|
||||
/*
|
||||
** Experimentation under Windows reveals that an owner-drawn
|
||||
** menu is expected to return the size of the content part of
|
||||
** the menu item, not including the checkmark nor the submenu
|
||||
** arrow. Windows adds those values itself and returns the
|
||||
** enlarged rectangle on subsequent WM_DRAWITEM messages.
|
||||
*/
|
||||
MEASUREITEMSTRUCT mis;
|
||||
mis.CtlType = ODT_MENU;
|
||||
mis.CtlID = 0;
|
||||
|
@ -792,7 +799,7 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
|
|||
lpitem->rect.right += mis.itemWidth;
|
||||
TRACE("id=%04x size=%dx%d\n",
|
||||
lpitem->wID, mis.itemWidth, mis.itemHeight);
|
||||
return;
|
||||
/* Fall through to get check/arrow width calculation. */
|
||||
}
|
||||
|
||||
if (lpitem->fType & MF_SEPARATOR)
|
||||
|
@ -808,6 +815,9 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
|
|||
lpitem->rect.right += arrow_bitmap_width;
|
||||
}
|
||||
|
||||
if (lpitem->fType & MF_OWNERDRAW)
|
||||
return;
|
||||
|
||||
if (IS_BITMAP_ITEM(lpitem->fType))
|
||||
{
|
||||
BITMAP bm;
|
||||
|
@ -1044,6 +1054,15 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
|
|||
|
||||
if (lpitem->fType & MF_OWNERDRAW)
|
||||
{
|
||||
/*
|
||||
** Experimentation under Windows reveals that an owner-drawn
|
||||
** menu is given the rectangle which includes the space it requested
|
||||
** in its response to WM_MEASUREITEM _plus_ width for a checkmark
|
||||
** and a popup-menu arrow. This is the value of lpitem->rect.
|
||||
** Windows will leave all drawing to the application except for
|
||||
** the popup-menu arrow. Windows always draws that itself, after
|
||||
** the menu owner has finished drawing.
|
||||
*/
|
||||
DRAWITEMSTRUCT dis;
|
||||
|
||||
dis.CtlType = ODT_MENU;
|
||||
|
@ -1064,7 +1083,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
|
|||
dis.hDC, dis.rcItem.left, dis.rcItem.top, dis.rcItem.right,
|
||||
dis.rcItem.bottom);
|
||||
SendMessageA( hwndOwner, WM_DRAWITEM, 0, (LPARAM)&dis );
|
||||
return;
|
||||
/* Fall through to draw popup-menu arrow */
|
||||
}
|
||||
|
||||
TRACE("rect={%d,%d,%d,%d}\n", lpitem->rect.left, lpitem->rect.top,
|
||||
|
@ -1074,52 +1093,58 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
|
|||
|
||||
rect = lpitem->rect;
|
||||
|
||||
if ((lpitem->fState & MF_HILITE) && !(IS_BITMAP_ITEM(lpitem->fType)))
|
||||
if ((menuBar) && (TWEAK_WineLook==WIN98_LOOK))
|
||||
DrawEdge(hdc, &rect, BDR_SUNKENOUTER, BF_RECT);
|
||||
else
|
||||
FillRect( hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT) );
|
||||
else
|
||||
FillRect( hdc, &rect, GetSysColorBrush(COLOR_MENU) );
|
||||
if (!(lpitem->fType & MF_OWNERDRAW))
|
||||
{
|
||||
if ((lpitem->fState & MF_HILITE) && !(IS_BITMAP_ITEM(lpitem->fType)))
|
||||
if ((menuBar) && (TWEAK_WineLook==WIN98_LOOK))
|
||||
DrawEdge(hdc, &rect, BDR_SUNKENOUTER, BF_RECT);
|
||||
else
|
||||
FillRect( hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT) );
|
||||
else
|
||||
FillRect( hdc, &rect, GetSysColorBrush(COLOR_MENU) );
|
||||
}
|
||||
|
||||
SetBkMode( hdc, TRANSPARENT );
|
||||
|
||||
/* vertical separator */
|
||||
if (!menuBar && (lpitem->fType & MF_MENUBARBREAK))
|
||||
if (!(lpitem->fType & MF_OWNERDRAW))
|
||||
{
|
||||
if (TWEAK_WineLook > WIN31_LOOK)
|
||||
{
|
||||
RECT rc = rect;
|
||||
rc.top = 3;
|
||||
rc.bottom = height - 3;
|
||||
DrawEdge (hdc, &rc, EDGE_ETCHED, BF_LEFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
|
||||
MoveTo16( hdc, rect.left, 0 );
|
||||
LineTo( hdc, rect.left, height );
|
||||
}
|
||||
}
|
||||
/* vertical separator */
|
||||
if (!menuBar && (lpitem->fType & MF_MENUBARBREAK))
|
||||
{
|
||||
if (TWEAK_WineLook > WIN31_LOOK)
|
||||
{
|
||||
RECT rc = rect;
|
||||
rc.top = 3;
|
||||
rc.bottom = height - 3;
|
||||
DrawEdge (hdc, &rc, EDGE_ETCHED, BF_LEFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
|
||||
MoveTo16( hdc, rect.left, 0 );
|
||||
LineTo( hdc, rect.left, height );
|
||||
}
|
||||
}
|
||||
|
||||
/* horizontal separator */
|
||||
if (lpitem->fType & MF_SEPARATOR)
|
||||
{
|
||||
if (TWEAK_WineLook > WIN31_LOOK)
|
||||
{
|
||||
RECT rc = rect;
|
||||
rc.left++;
|
||||
rc.right--;
|
||||
rc.top += SEPARATOR_HEIGHT / 2;
|
||||
DrawEdge (hdc, &rc, EDGE_ETCHED, BF_TOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
|
||||
MoveTo16( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2 );
|
||||
LineTo( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 );
|
||||
}
|
||||
return;
|
||||
/* horizontal separator */
|
||||
if (lpitem->fType & MF_SEPARATOR)
|
||||
{
|
||||
if (TWEAK_WineLook > WIN31_LOOK)
|
||||
{
|
||||
RECT rc = rect;
|
||||
rc.left++;
|
||||
rc.right--;
|
||||
rc.top += SEPARATOR_HEIGHT / 2;
|
||||
DrawEdge (hdc, &rc, EDGE_ETCHED, BF_TOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
|
||||
MoveTo16( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2 );
|
||||
LineTo( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup colors */
|
||||
|
@ -1152,45 +1177,50 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
|
|||
{
|
||||
INT y = rect.top + rect.bottom;
|
||||
|
||||
/* Draw the check mark
|
||||
*
|
||||
* FIXME:
|
||||
* Custom checkmark bitmaps are monochrome but not always 1bpp.
|
||||
*/
|
||||
if (!(lpitem->fType & MF_OWNERDRAW))
|
||||
{
|
||||
/* Draw the check mark
|
||||
*
|
||||
* FIXME:
|
||||
* Custom checkmark bitmaps are monochrome but not always 1bpp.
|
||||
*/
|
||||
|
||||
if (lpitem->fState & MF_CHECKED)
|
||||
{
|
||||
HBITMAP bm = lpitem->hCheckBit ? lpitem->hCheckBit :
|
||||
((lpitem->fType & MFT_RADIOCHECK) ? hStdRadioCheck : hStdCheck);
|
||||
HDC hdcMem = CreateCompatibleDC( hdc );
|
||||
if (lpitem->fState & MF_CHECKED)
|
||||
{
|
||||
HBITMAP bm = lpitem->hCheckBit ? lpitem->hCheckBit :
|
||||
((lpitem->fType & MFT_RADIOCHECK) ? hStdRadioCheck : hStdCheck);
|
||||
HDC hdcMem = CreateCompatibleDC( hdc );
|
||||
|
||||
SelectObject( hdcMem, bm );
|
||||
BitBlt( hdc, rect.left, (y - check_bitmap_height) / 2,
|
||||
check_bitmap_width, check_bitmap_height,
|
||||
hdcMem, 0, 0, SRCCOPY );
|
||||
DeleteDC( hdcMem );
|
||||
}
|
||||
else if (lpitem->hUnCheckBit)
|
||||
{
|
||||
HDC hdcMem = CreateCompatibleDC( hdc );
|
||||
SelectObject( hdcMem, bm );
|
||||
BitBlt( hdc, rect.left, (y - check_bitmap_height) / 2,
|
||||
check_bitmap_width, check_bitmap_height,
|
||||
hdcMem, 0, 0, SRCCOPY );
|
||||
DeleteDC( hdcMem );
|
||||
}
|
||||
else if (lpitem->hUnCheckBit)
|
||||
{
|
||||
HDC hdcMem = CreateCompatibleDC( hdc );
|
||||
|
||||
SelectObject( hdcMem, lpitem->hUnCheckBit );
|
||||
BitBlt( hdc, rect.left, (y - check_bitmap_height) / 2,
|
||||
check_bitmap_width, check_bitmap_height,
|
||||
hdcMem, 0, 0, SRCCOPY );
|
||||
DeleteDC( hdcMem );
|
||||
}
|
||||
SelectObject( hdcMem, lpitem->hUnCheckBit );
|
||||
BitBlt( hdc, rect.left, (y - check_bitmap_height) / 2,
|
||||
check_bitmap_width, check_bitmap_height,
|
||||
hdcMem, 0, 0, SRCCOPY );
|
||||
DeleteDC( hdcMem );
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the popup-menu arrow */
|
||||
if (lpitem->fType & MF_POPUP)
|
||||
{
|
||||
HDC hdcMem = CreateCompatibleDC( hdc );
|
||||
HBITMAP hOrigBitmap;
|
||||
|
||||
SelectObject( hdcMem, hStdMnArrow );
|
||||
hOrigBitmap = SelectObject( hdcMem, hStdMnArrow );
|
||||
BitBlt( hdc, rect.right - arrow_bitmap_width - 1,
|
||||
(y - arrow_bitmap_height) / 2,
|
||||
arrow_bitmap_width, arrow_bitmap_height,
|
||||
hdcMem, 0, 0, SRCCOPY );
|
||||
SelectObject( hdcMem, hOrigBitmap );
|
||||
DeleteDC( hdcMem );
|
||||
}
|
||||
|
||||
|
@ -1198,6 +1228,10 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
|
|||
rect.right -= arrow_bitmap_width;
|
||||
}
|
||||
|
||||
/* Done for owner-drawn */
|
||||
if (lpitem->fType & MF_OWNERDRAW)
|
||||
return;
|
||||
|
||||
/* Draw the item text or bitmap */
|
||||
if (IS_BITMAP_ITEM(lpitem->fType))
|
||||
{ int top;
|
||||
|
@ -2119,9 +2153,9 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
|
|||
{
|
||||
if (menu->wFlags & MF_POPUP)
|
||||
{
|
||||
rect.left = wndPtr->rectWindow.left + item->rect.right-arrow_bitmap_width;
|
||||
rect.left = wndPtr->rectWindow.left + item->rect.right - GetSystemMetrics(SM_CXBORDER);
|
||||
rect.top = wndPtr->rectWindow.top + item->rect.top;
|
||||
rect.right = item->rect.left - item->rect.right + 2*arrow_bitmap_width;
|
||||
rect.right = item->rect.left - item->rect.right + GetSystemMetrics(SM_CXBORDER);
|
||||
rect.bottom = item->rect.top - item->rect.bottom;
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue